dztkdx 2021-09-25 16:10 采纳率: 30%
浏览 82
已结题

关于爬虫同步方法修改为异步协程的问题

具体过程就是,在写爬取一个小说网站的小爬虫
大概架构是:
1、先从目录页入手找到各个子页面的地址
2、再通过子页面地址用正则抓取到正文内容
3、将上述第二部,抓取正文内容的过程,改为异步协程的方法,同时抓取

现在1、2步以实现,在同步状态下可以正常运行;但是根据小子网上学的改为异步协程方法进行修改后;却报错无法执行,望老鸟指教
以下是拿来练手的小说地址:

img

img

img

报错截图

img

源代码:

import re 
import requests
import asyncio  
import aiohttp  
import aiofiles 
import json

#用来提取子页面地址的正则
obj1=re.compile(r'<a class="subscri" href="//read.qidian.com/hankread/1030136856/94755936/" target="_blank"><!--<em class="btn"><b class="iconfont">&#xe636;</b>分卷阅读</em>--></a>.*?<ul class="cf">(?P<all>.*?) <div class="book-content-wrap cf">',re.S)
obj2=re.compile(r'<li data-rid=.*?><a href="(?P<url>.*?)'
                r'title=".*?">(?P<name>.*?)</a>',re.S)

#用来提取小说正文的正则
obj3=re.compile(r'<div class="read-content j_readContent" id="">(?P<main>.*?)</div>.*?<div class="admire-wrap">',re.S)

headers={
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36 OPR/78.0.4093.184'
}

#提取到的页面子链接需要补充:https:
child_supplement='https:'

#拿到章节子页面地址
async def getintroduction(url,headers):
    resp=requests.get(url)
    chapter=resp.text
    #print(resp.text)
    urls=[]  #准备一个列表放提取到的url
    #用正则提取章节子页面地址
    #第一次先提取整个网页中的目录模块
    result=obj1.finditer(chapter)
    for it in result:
        #print(it.group('all'))
        table=it.group('all')
    #第二次再分开提取每个章节的URL
    content=obj2.finditer(table)
    for it in content:
        #print(it.group('name'))
        #print(it.group('url'))
        name = it.group('name')
        url =child_supplement+it.group('url')  #对提取到的链接进行拼接
        #准备异步任务,把提取到的url,放到一个列表里
        urls.append(aiodownload(url,name))
        #print(urls)
    resp.close()
    await asyncio.wait(urls)



#读取子页面的正文内容
async def aiodownload(url,name):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:  # 得到每个章节子页面的信息
            content=await resp.json()  #读到的内容存储
            #print(content)
            result=obj3.finditer(content)
            for it in result:
                #print(it.group('main'))
                book=it.group('main')
                async with aiofiles.open('4.8-book/'+name,mode='w',encoding='UTF-8') as f: 
                    await f.write(book)
                print('完成')





if __name__=='__main__':
    b_id='1030136856'
    url='https://book.qidian.com/info/'+b_id+'/#Catalog'
    #getintroduction(url,headers=headers)
    asyncio.run(getintroduction(url,headers=headers))

  • 写回答

1条回答 默认 最新

  • 咕泡-三木 2021-09-26 13:46
    关注

    报错来自于aiohttp,传递给aiohttp的URL有误,解析不了所以报错了
    URL有误是因为正则结果不对,把提取URL的正则改一下就好了

    obj2 = re.compile(
        r'<li data-rid=.*?><a href="(?P<url>.*?)".*? title=".*?">(?P<name>.*?)</a>', re.S
    )
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 10月18日
  • 已采纳回答 10月10日
  • 专家修改了标签 10月8日
  • 修改了问题 10月1日
  • 展开全部

悬赏问题

  • ¥20 用泊松逆高斯分布拟合已知数据
  • ¥15 web课程,怎么做啊😭没好好听课 根本不知道怎么下手
  • ¥15 做一个关于单片机的比较难的代码,然后搞一个PPT进行解释
  • ¥15 python提取.csv文件中的链接会经常出现爬取失败
  • ¥15 数据结构中的数组地址问题
  • ¥15 maya的mel里,怎样先选择模型A,然后利用mel脚本自动选择有相同名字的模型B呢。
  • ¥15 Python题,根本不会啊
  • ¥15 会会信号与系统和python的来
  • ¥15 关于#python#的问题
  • ¥20 oracle RAC 怎么配置啊,配置