异步加速爬取小说
### 用python爬取小说在同步状态下,下载缓慢,所以用asynio/await写了一个异步的爬取(仅用于学习!)1. 获取各章节的网址和题目(从12开始取值是为了过滤掉最新章节对顺序的影响,包括**xpath的值**,具体需要对网页结构进行分析,**不能直接套用**)
```
async def get_link(url):
req = requests.get(url, headers=HEADERS)
req.encoding = 'gbk'
Xpath = parsel.Selector(req.text)
links = Xpath.xpath('/html/body/div/dl/dd/a/@href').extract()
full_links =
names = Xpath.xpath('/html/body/div/dl/dd/a/text()').extract()
name_list =
name_link = zip(full_links, name_list)
async with httpx.AsyncClient() as client:
task = []
for link, name in name_link:
task.append(get_text(client, name, link))
await asyncio.wait(task)
save_text(name_list)
```
> 这其中使用httpx异步请求,可以加快访问各章节的速度
> 然后将各章节任务添加到任务队列中,交由asynio处理
2. 各章节任务就是获取章节内容,然后保存即可。但是由于asynio的任务的处理是无序的,所有使用一个字典进行缓存返回内容,在缓存完毕时,将字典内容写入到txt中。
```
async def get_text(client, name, link):
req = await client.get(link, headers=HEADERS, timeout=None)
html = etree.HTML(req.text)
text = html.xpath('//*[@id="content"]/text()')
await save_text_dic(name, text[:-2])
```
3.这个地方最好边缓存边写入,类似与生产者消费者,才疏学浅,没有实现思路)
```
async def save_text_dic(name, texts):
# TODO:边缓存边写入
dic = texts
```
4.将字典中内容按照爬取的顺序写入即可。
```
def save_text(name_list):
# 文件目录
path = ""
if not os.path.exists(path):
os.mkdir(path)
#小说名
f = open(f'{path}/小说名.txt', 'a', encoding='utf-8')
# async with open(f"./result/{name}.txt", 'w', encoding="utf-8") as f:
for name in track(name_list):
f.write(name)
f.write('\n\n')
for text in dic:
# print(text)
f.write(text)
f.write('\n\n')
f.write('\n')
```
5.最后主函数和一些类变量(偷懒没有将所有函数写在类中)
```
#用于拼接章节网址的基础网址
BASEURL = ""
#字典声明
dic = {}
```
```
if __name__ == '__main__':
#具体某本小说的网址
url = ''"
loop = asyncio.get_event_loop()
loop.run_until_complete(get_link(url))
```
---
写的很简陋,主要是为了学习一下异步和协程。
与同步下载相比,确实快了许多,但是会偶尔因为httpx的连接超时导致中断,想排查的时候结果成功了== 本帖最后由 jasony0 于 2021-12-5 22:48 编辑
我是在服务器上运行的,在本地运行可能由于请求过于密集过快被拒绝。如果遇到可以反馈一下,共同学习!
将项目里用到的文件打包出来,运行时保存小说的路径需要按情况调整,其他的文件名按需调整即可。
如果引入tools下的header失败,最简单处理就是将tools下的代码复制到主文件中:lol(由于我是在最外层目录运行的主文件,所以主文件中写的路径是在我环境终的路径,具体需要按需调整)
在调试时最好不要过密集的发起请求,对他人服务器造成损失。{:1_893:} 学习了感谢分享 学习了感谢分享,如果有成品更好:lol 这么多段代码,咋样的,小白迷惑 Asy_少洋 发表于 2021-12-5 10:17
这么多段代码,咋样的,小白迷惑
可以看一下我新回复的文件{:1_896:} jasony0 发表于 2021-12-5 22:47
可以看一下我新回复的文件
在哪里,没看到呀,大佬 Asy_少洋 发表于 2021-12-6 09:18
在哪里,没看到呀,大佬
我置顶了,第一条评论就是
页:
[1]