php多线程抓取多个网页(行行网电子书多线程-撸代码代码非常简单-写在前面 )
优采云 发布时间: 2022-03-29 16:05php多线程抓取多个网页(行行网电子书多线程-撸代码代码非常简单-写在前面
)
星星网电子书多线程——写在前面
最近想找几本电子书看,翻了翻,然后找到了一个叫周渡的网站,网站很好,简单清爽,有书很多,而且都是在百度上打开的,网盘可以直接下载,更新速度也还行,就爬了上去。这篇文章可以文章学习,这么好的分享网站,尽量不要爬,会影响别人访问速度。需要数据的可以在我的博客下评论,我会发给你,QQ,邮箱什么的。
这个网站页面的逻辑很简单。我翻阅了图书详情页面,它看起来是这样的。我们只需要循环生成这些页面的链接,然后就可以爬取了。为了速度,我使用多线程。, 你可以试试看。如果想爬取后面的数据,就在本博客下方发表评论,不要乱搞别人的服务器。
http://www.ireadweek.com/index.php/bookInfo/11393.html
http://www.ireadweek.com/index.php/bookInfo/11.html
....
星星网电子书多线程-代码
代码非常简单。以我们之前的教程做铺垫,用很少的代码就可以实现完整的功能。最后将采集的内容写入csv文件,(什么是csv,百度知道)这段代码是IO密集型操作,我们使用aiohttp模块来编写。
第1步
连接 URL 并启动线程。
import requests
# 导入协程模块
import asyncio
import aiohttp
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
"Host": "www.ireadweek.com",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"}
async def get_content(url):
print("正在操作:{}".format(url))
# 创建一个session 去获取数据
async with aiohttp.ClientSession() as session:
async with session.get(url,headers=headers,timeout=3) as res:
if res.status == 200:
source = await res.text() # 等待获取文本
print(source)
if __name__ == '__main__':
url_format = "http://www.ireadweek.com/index.php/bookInfo/{}.html"
full_urllist = [url_format.format(i) for i in range(1,11394)] # 11394
loop = asyncio.get_event_loop()
tasks = [get_content(url) for url in full_urllist]
results = loop.run_until_complete(asyncio.wait(tasks))
上面的代码可以同步开启N个多线程,但是这样很容易导致其他人的服务器瘫痪。因此,我们必须限制并发数。下面的代码,你可以试着把它放在指定的位置。
sema = asyncio.Semaphore(5)
# 为避免爬虫一次性请求次数太多,控制一下
async def x_get_source(url):
with(await sema):
await get_content(url)
第2步
为了处理捕获的 Web 源代码并提取我们想要的元素,我添加了一个使用 lxml 提取数据的方法。
def async_content(tree):
title = tree.xpath("//div[@class='hanghang-za-title']")[0].text
# 如果页面没有信息,直接返回即可
if title == '':
return
else:
try:
description = tree.xpath("//div[@class='hanghang-shu-content-font']")
author = description[0].xpath("p[1]/text()")[0].replace("作者:","") if description[0].xpath("p[1]/text()")[0] is not None else None
cate = description[0].xpath("p[2]/text()")[0].replace("分类:","") if description[0].xpath("p[2]/text()")[0] is not None else None
douban = description[0].xpath("p[3]/text()")[0].replace("豆瓣评分:","") if description[0].xpath("p[3]/text()")[0] is not None else None
# 这部分内容不明确,不做记录
#des = description[0].xpath("p[5]/text()")[0] if description[0].xpath("p[5]/text()")[0] is not None else None
download = tree.xpath("//a[@class='downloads']")
except Exception as e:
print(title)
return
ls = [
title,author,cate,douban,download[0].get('href')
]
return ls
第 3 步
数据格式化后,将其保存为 csv 文件,然后收工!
print(data)
with open('hang.csv', 'a+', encoding='utf-8') as fw:
writer = csv.writer(fw)
writer.writerow(data)
print("插入成功!")
星星网电子书多线程——运行代码,看看结果
因为这可能涉及到从其他人的服务器获取重要数据,所以代码不会上传到github。需要的可以留言,我会单独发给你