python异步协程
本帖最后由 是肥宅SRP啊 于 2023-4-29 14:38 编辑没加入协程之前,我是可以正常获取到href里的各章网址,也是可以获取到各章节的文字内容的,但是加入协程之后就不行。
协程学的一知半解的,我不知道哪里错了,help!!
import asyncio
import aiohttp
import aiofiles
import requests
from lxml import etree
#获取URL
def get_url():
url = "https://www.zanghaihua.org/book/40627/"
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.12022 SLBChan/8"
}
http = requests.get(url,headers = headers)
http.encoding = "gbk"
parse_html = etree.HTML(http.text)
hrefs = parse_html.xpath("//li/a/@href")
return hrefs
#获取文本
async def get_text(url):
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.12022 SLBChan/8"
}
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as res:
res.encoding = "utf-8"
parse_html = await res.text()
parse_html = etree.HTML(parse_html)
content = parse_html.xpath('//div[@class="content"]/text()')
title = parse_html.xpath('//div[@class="reader-main"]/h1/text()')
# print(title)
# print(content)
async with aiofiles.open(f"{title}.text",mode = "w", coding = "utf-8") as f:
await f.write(content)
#创建协程_
async def get_task(href_list):
tasks = []
for href in href_list:
t = asyncio.create_task(get_text(href))
tasks.append(t)
await asyncio.wait(tasks)
def main():
href_lists = get_url()
asyncio.run(get_task(href_lists))
从你的代码来看,你已经开始了异步协程的学习,并将其应用到了抓取网页的任务中。在这里,我会给出一些建议来帮助你改进代码。
1.aiohttp 的响应对象 res 没有 encoding 属性,因此在这里设置 res.encoding = "utf-8" 是错误的。你可以在 res.text() 函数中传入 encoding 参数来指定编码方式,如: await res.text(encoding='utf-8') 。
2. 使用 aiofiles.open() 时,你应该使用 encoding 参数而不是 coding 。
3.title 和 content 都是列表类型,而不是字符串。在写入文件之前,需要将它们转换为字符串。
这里是修改后的代码:
import asyncio
import aiohttp
import aiofiles
import requests
from lxml import etree
#获取URL
def get_url():
url = "https://www.zanghaihua.org/book/40627/"
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.12022 SLBChan/8"
}
http = requests.get(url,headers = headers)
http.encoding = "gbk"
parse_html = etree.HTML(http.text)
hrefs = parse_html.xpath("//li/a/@href")
return hrefs
#获取文本
async def get_text(url):
headers = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.12022 SLBChan/8"
}
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as res:
parse_html = await res.text(encoding='utf-8')
parse_html = etree.HTML(parse_html)
content = parse_html.xpath('//div[@class="content"]/text()')
title = parse_html.xpath('//div[@class="reader-main"]/h1/text()')
async with aiofiles.open(f"{title}.txt", mode="w", encoding="utf-8") as f:
await f.write("\n".join(content))
#创建协程
async def get_task(href_list):
tasks = []
for href in href_list:
t = asyncio.create_task(get_text(href))
tasks.append(t)
await asyncio.wait(tasks)
def main():
href_lists = get_url()
asyncio.run(get_task(href_lists))
if __name__ == "__main__":
main()
经过这些修改,代码应该能正常运行并获取各章节的文本内容。希望这对你有所帮助!如果还有其他问题,请随时提问。 你确定你不用协程就可以? 根据您提供的代码,似乎没有立即显然的问题。但是我注意到您在async with aiofiles.open处使用了title变量而不是title。
由于title实际上是一个列表,这可能会导致文件名与内容不匹配。您可以尝试更新代码,使用title来获取第一个元素作为字符串。例如:
async with aiofiles.open(f"{title}.text", mode="w", encoding="utf-8") as f:
await f.write(content)
希望这会解决您的问题! isdkz 发表于 2023-4-29 11:34
从你的代码来看,你已经开始了异步协程的学习,并将其应用到了抓取网页的任务中。在这里,我会给出一些建议 ...
老师你好,我按照你修改过后的代码运行了一下,是能运行的,非常感谢。我还有一个小问题想问一下,就是把文本内容爬下来之后,我在pycharm里直接打开的话,在每段文字开头会有四个NBSP的字样,用文档打开的话没有,但是有点丑,每段空了四个空格。我去页面源代码看了一下看到他是有这个“ ”,我想用replace把他replace掉,但是怎么好像没有用?
陶远航 发表于 2023-4-29 12:11
根据您提供的代码,似乎没有立即显然的问题。但是我注意到您在async with aiofiles.open处使用了title变量 ...
谢谢你,我发现了这个错误了,感谢感谢! 是肥宅SRP啊 发表于 2023-4-29 14:18
老师你好,我按照你修改过后的代码运行了一下,是能运行的,非常感谢。我还有一个小问题想问一下,就是把 ...
.replace(" ", '') 不行吗? isdkz 发表于 2023-4-29 14:20
.replace(" ", '') 不行吗?
await f.write("\n".join(content).replace(" ",""))是这样写吗?我这样写好像没啥变化的样子不知道是不是我写错了 是肥宅SRP啊 发表于 2023-4-29 14:24
await f.write("\n".join(content).replace(" ",""))是这样写吗?我这样写好像没啥变化的样子不知道 ...
对的,没有什么变化的话你可以把对应的文件放上来给我看一下,最好压缩放到附件里 isdkz 发表于 2023-4-29 14:32
对的,没有什么变化的话你可以把对应的文件放上来给我看一下,最好压缩放到附件里
是代码文件和爬取的小说内容吗?我放了一个第五章,因为他是从第五章开始出现那个的。 是肥宅SRP啊 发表于 2023-4-29 14:40
是代码文件和爬取的小说内容吗?我放了一个第五章,因为他是从第五章开始出现那个的。
你放的那个文件我看了,不是多了 而是多了 \xa0 的一个不可见字符
用 .replace('\xa0', '') 来替换掉
isdkz 发表于 2023-4-29 14:47
你放的那个文件我看了,不是多了 而是多了 \xa0 的一个不可见字符
用 .replace('\xa0', '') 来 ...
好了!谢谢你!
页:
[1]