鱼C论坛

 找回密码
 立即注册
查看: 1148|回复: 11

[已解决]python异步协程

[复制链接]
发表于 2023-4-29 11:31:16 | 显示全部楼层 |阅读模式
10鱼币
本帖最后由 是肥宅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")[16:87]
    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))
最佳答案
2023-4-29 11:31:17
从你的代码来看,你已经开始了异步协程的学习,并将其应用到了抓取网页的任务中。在这里,我会给出一些建议来帮助你改进代码。

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")[16:87]
    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[0]}.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()

经过这些修改,代码应该能正常运行并获取各章节的文本内容。希望这对你有所帮助!如果还有其他问题,请随时提问。

新建文件夹.rar

3.18 KB, 下载次数: 1

最佳答案

查看完整内容

从你的代码来看,你已经开始了异步协程的学习,并将其应用到了抓取网页的任务中。在这里,我会给出一些建议来帮助你改进代码。 1. aiohttp 的响应对象 res 没有 encoding 属性,因此在这里设置 res.encoding = "utf-8" 是错误的。你可以在 res.text() 函数中传入 encoding 参数来指定编码方式,如: await res.text(encoding='utf-8') 。 2. 使用 aiofiles.open() 时,你应该使用 encoding 参数而不是 coding 。 3. tit ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-29 11:31:17 | 显示全部楼层    本楼为最佳答案   
从你的代码来看,你已经开始了异步协程的学习,并将其应用到了抓取网页的任务中。在这里,我会给出一些建议来帮助你改进代码。

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")[16:87]
    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[0]}.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()

经过这些修改,代码应该能正常运行并获取各章节的文本内容。希望这对你有所帮助!如果还有其他问题,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-29 12:08:13 | 显示全部楼层
你确定你不用协程就可以?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-29 12:11:56 | 显示全部楼层
根据您提供的代码,似乎没有立即显然的问题。但是我注意到您在async with aiofiles.open处使用了title变量而不是title[0]。

由于title实际上是一个列表,这可能会导致文件名与内容不匹配。您可以尝试更新代码,使用title[0]来获取第一个元素作为字符串。例如:
async with aiofiles.open(f"{title[0]}.text", mode="w", encoding="utf-8") as f:
    await f.write(content)
希望这会解决您的问题!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-4-29 14:18:33 | 显示全部楼层
isdkz 发表于 2023-4-29 11:34
从你的代码来看,你已经开始了异步协程的学习,并将其应用到了抓取网页的任务中。在这里,我会给出一些建议 ...

老师你好,我按照你修改过后的代码运行了一下,是能运行的,非常感谢。我还有一个小问题想问一下,就是把文本内容爬下来之后,我在pycharm里直接打开的话,在每段文字开头会有四个NBSP的字样,用文档打开的话没有,但是有点丑,每段空了四个空格。我去页面源代码看了一下看到他是有这个“    ”,我想用replace把他replace掉,但是怎么好像没有用?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-4-29 14:19:42 | 显示全部楼层
陶远航 发表于 2023-4-29 12:11
根据您提供的代码,似乎没有立即显然的问题。但是我注意到您在async with aiofiles.open处使用了title变量 ...

谢谢你,我发现了这个错误了,感谢感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-29 14:20:40 | 显示全部楼层
是肥宅SRP啊 发表于 2023-4-29 14:18
老师你好,我按照你修改过后的代码运行了一下,是能运行的,非常感谢。我还有一个小问题想问一下,就是把 ...

.replace(" ", '') 不行吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-4-29 14:24:19 | 显示全部楼层
isdkz 发表于 2023-4-29 14:20
.replace(" ", '') 不行吗?

await f.write("\n".join(content).replace(" ",""))是这样写吗?我这样写好像没啥变化的样子不知道是不是我写错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-29 14:32:19 | 显示全部楼层
是肥宅SRP啊 发表于 2023-4-29 14:24
await f.write("\n".join(content).replace(" ",""))是这样写吗?我这样写好像没啥变化的样子不知道 ...

对的,没有什么变化的话你可以把对应的文件放上来给我看一下,最好压缩放到附件里
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-4-29 14:40:20 | 显示全部楼层
isdkz 发表于 2023-4-29 14:32
对的,没有什么变化的话你可以把对应的文件放上来给我看一下,最好压缩放到附件里

是代码文件和爬取的小说内容吗?我放了一个第五章,因为他是从第五章开始出现那个的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-29 14:47:31 | 显示全部楼层
是肥宅SRP啊 发表于 2023-4-29 14:40
是代码文件和爬取的小说内容吗?我放了一个第五章,因为他是从第五章开始出现那个的。

你放的那个文件我看了,不是多了   而是多了 \xa0 的一个不可见字符

用 .replace('\xa0', '') 来替换掉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-4-29 15:10:58 | 显示全部楼层
isdkz 发表于 2023-4-29 14:47
你放的那个文件我看了,不是多了   而是多了 \xa0 的一个不可见字符

用 .replace('\xa0', '') 来 ...

好了!谢谢你!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 11:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表