好友
阅读权限25
听众
最后登录1970-1-1
|
本帖最后由 Cool_Breeze 于 2021-1-11 21:32 编辑
因为网站页面很简单!非常适合新手练习!
没有开启多线程爬取网站,只是开启了多线程处理数据,供大家学习参考!(这里只是给大家参考一下多线程!)
为什么没有开启多线程访问网页呢?
因为我有一次在某个论坛发布了一篇帖子,多线程爬取MP3。
当时是晚上12点发布的,结果第二天早上去该网站播放音乐,播放不了了!
不知道是我发布帖子的原因,还是对方服务器的问题(总感觉对不住人家!毕竟是小网站嘛!)
然后我就把帖子也删了!
[Python] 纯文本查看 复制代码 # coding=utf-8
# python 3.7
import urllib.request,urllib.error
import re
import threading
import multiprocessing
from time import sleep
# 保存网页内容
def dataFilter():
# 设置了全局参数(方便),最好还是传参数
global htmlQueue # 任务队列
global some # log文件
global lock # 文件锁
while True:
html = htmlQueue.get() # 从任务队列中获取任务(数据)
if html is None: exit(0) #退出线程
# 正则表达式获取数据
favorites = re.compile(r'title="收藏">(\d+)</a>').findall(html)
centent = re.compile(r'id="txt-\d+-\d+">(.*?)</p>').findall(html)
# 收藏值大于 70 的保存
tmp = []
lock.acquire() # 当文件没有其他线程写入时写入文件
for n in range(len(favorites)):
if int(favorites[n]) > 70:
tmp.append(favorites[n])
index = n*2
tmp.append(centent[index])
tmp.append(centent[index+1])
some.write(','.join(tmp) + '\n')
some.flush()
tmp.clear()
lock.release() # 写入文件完成,报告(默认为 1 )
# 获取一页网页数据
def GetHtml(url):
# 浏览器头部信息
head = {
'Accept-Language': 'zh-CN,zh;q=0.9',
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.30 Safari/537.36"
}
req = urllib.request.Request(url=url, headers=head)
# 这里可以加入 try 代码,处理打开网页失败情况
response = urllib.request.urlopen(req)
return response.read().decode('utf-8')
# 爬取网站IP
url = 'https://www.woyaogexing.com/name/ql/'
# 第一页
print(f'正在爬取第一页 {url}')
parent = GetHtml(url)
# 获取当前页面包含的所有下一页的IP
page = re.compile(r'/name/ql/(index_\d+.html)').findall(parent)
page = set(page) # 集合去重
page = list(page) # 转换回列表
page.sort() # 排序
# 第一页包含的所有页面IP
print(page)
# log保存文件
some = open('some.txt', 'w', encoding='utf-8')
some.write('收藏数, 签名1, 签名2\n')
# 写入文件锁,只能单个写入,避免数据混淆
# 默认值为 1 (单个线程写入文件)
lock = threading.Semaphore()
# 线程任务队列
htmlQueue = multiprocessing.Queue()
# 管理所有线程的容器
threadList = []
# 开启4个线程
# 设置为守护线程,主线程退出后结束所有子线程,避免线程悬挂
maxThreadN = 4
for n in range(maxThreadN):
tmp = threading.Thread(target=dataFilter, daemon=True)
threadList.append(tmp)
tmp.start()
# 向线程任务队列提交任务
for n in page:
print(f'正在爬取 {n}')
sleep(2) # 加上等待时间2秒,我们要对网站温柔一些
htmlQueue.put(GetHtml(url + n))
# 任务完成,提交数据 None 结束所有线程
for n in range(maxThreadN):
htmlQueue.put(None)
# 等待所有线程结束
for th in threadList:
th.join()
# 最后关闭 log 文件
some.close()
input('所有任务完成!')
运行画面:
正在爬取第一页 https://www.woyaogexing.com/name/ql/
['index_2.html', 'index_3.html', 'index_4.html', 'index_5.html', 'index_6.html']
正在爬取 index_2.html
正在爬取 index_3.html
正在爬取 index_4.html
正在爬取 index_5.html
正在爬取 index_6.html
所有任务完成!
日志文件内容:
收藏数, 签名1, 签名2
121,ʕ•̫͡•ʔ想揪吗,ʔ•̫͡•ʕ诶~ 就不让你揪
135,茶尾布朗熊.,短卷可妮兔.
80,仲夏蝉鸣.,悸动难平.
113,星洲泛泛.,桃花灼灼.
139,没人暖手手,那就揣兜兜
补一张流程图,方便理解
以上有什么不对之处,请大家指正! |
-
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|