懒人畅听网,有声小说类目数据采集,多线程速采案例,Python爬虫120例之23例
Posted 梦想橡皮擦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了懒人畅听网,有声小说类目数据采集,多线程速采案例,Python爬虫120例之23例相关的知识,希望对你有一定的参考价值。
多线程在 Python 爬虫学习过程中应用落地,提速,提速,再提速。
目标站点分析
本次要抓取的目标为懒人畅听网,其中我随机选择了一个分类,有声小说频道,其余频道可使用雷同的办法抓取,增加遍历之后,可以对全站进行抓取。
列表页分页规则如下
本次依旧只对列表页数据进行提取,只增加多线程模块 threading
的应用,提高采集效率。
http://www.lrts.me/book/category/1/recommend/1/20
http://www.lrts.me/book/category/1/recommend/2/20
提取规则模板如下:
http://www.lrts.me/book/category/1/recommend/页码/20
全站页码数,可以直接人眼读取,如果增加动态获取,提取读取一下分页处数据即可。
提取最终的数据源如下图所示,包括书名,作者,主播三部分内容。
编码时间
本次案例中对于多线程部分,除共享全局变量外,增加信号量机制,即限制线程并发数量。
信号量机制的简单 Demo 如下所示:
import threading
import time
def run(n, semaphore):
# 加锁
semaphore.acquire()
time.sleep(2)
print(f'正在运行线程{n}')
# 释放锁
semaphore.release()
if __name__ == '__main__':
num = 0
# 最多允许 3 个线程同时运行
semaphore = threading.BoundedSemaphore(3)
for i in range(10):
t = threading.Thread(target=run, args=(f'线程号:{i}', semaphore))
t.start()
while threading.active_count() != 1:
pass
else:
print('所有线程运行完毕')
运行代码,会发现先运行 3 个线程,再运行 3 个线程,当然同时运行的线程之间是没有先后顺序的。
信号量,即使用 threading
模块的 BoundedSemaphore
类,该类可以设置允许一定数量的线程更改数据,即最多可同时运行几个线程。
代码完整案例如下所示
import threading
from threading import Lock,Thread
import random,requests
from lxml import etree
def get_headers():
uas = [
"Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
]
ua = random.choice(uas)
headers = {
"user-agent": ua,
"referer": "https://www.baidu.com/"
}
return headers
def run(url,semaphore):
headers = get_headers()
semaphore.acquire() #加锁
res = requests.get(url,headers=headers,timeout=5)
if res:
text = res.text
element = etree.HTML(text)
titles = element.xpath('//a[@class="book-item-name"]/text()')
authors = element.xpath('//a[@class="author"]/text()')
weakens = element.xpath('//a[@class="g-user-shutdown"]/text()')
save(url,titles,authors,weakens)
semaphore.release() #释放
def save(url,titles,authors,weakens):
data_list = zip(titles,authors,weakens)
for item in data_list:
with open("./data.csv","a+",encoding="utf-8") as f:
f.write(f"{item[0]},{item[1]},{item[2]}\\n")
print(url,"该URL地址数据写入完毕")
if __name__== '__main__':
lock = Lock()
url_format = 'https://www.lrts.me/book/category/1/recommend/{}/20'
# 拼接URL,全局共享变量
urls = [url_format.format(i) for i in range(1, 1372)]
l = []
semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行
for url in urls:
t = threading.Thread(target=run,args=(url,semaphore))
t.start()
while threading.active_count() !=1:
pass
else:
print('所有线程运行完毕')
代码中 threading.active_count()
部分,用于检测是否存在活跃线程,如无,程序结束。
运行代码,得到如下结果,至此第 23 例已经学习完毕。
收藏时间
代码仓库地址:https://codechina.csdn.net/hihell/python120,去给个关注或者 Star 吧。
来都来了,不发个评论,点个赞,收个藏吗?
今天是持续写作的第 203 / 365 天。
可以关注我,点赞我、评论我、收藏我啦。
更多精彩
以上是关于懒人畅听网,有声小说类目数据采集,多线程速采案例,Python爬虫120例之23例的主要内容,如果未能解决你的问题,请参考以下文章