python中怎么实现一个多线程爬虫
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,这篇文章给大家介绍python中怎么实现一个多线程爬虫,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。开发环境:ubuntu16.04,python3.6,bs4,virtuale
千家信息网最后更新 2025年12月03日python中怎么实现一个多线程爬虫
这篇文章给大家介绍python中怎么实现一个多线程爬虫,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
开发环境:
ubuntu16.04,python3.6,bs4,virtualenv(虚拟环境)
创建虚拟环境:
创建项目文件夹,并为项目创建虚拟环境,利用pip安装相关包
mkdir mutiThreadCrawier
cd mutiThreadCrawier
mkdir content #存爬下来的页面
virtualenv env --python =python3.6 #创建虚拟环境
source env/bin/activate #使虚拟环境生效导包:
import time
import re
import threading
import urllib
import requests
from bs4 import BeautifulSoup定义变量
g_mutex = threading.Condition() # 可以加锁/释放锁
print(g_mutex)
print(type(g_mutex))
g_urls = [] # 存放解析出来的url对应的网页源码
g_queue_urls = [] # 待爬取的url
g_exist_urls = [] # 已经爬过的url
g_failed_urls = [] # 失败的链接
g_total_count = 0 # 已经下载的页面的计数器定义线程类:
创建一个线程类,继承于threading.Thread,并进构造,在run函数中根据url路径请求网络连接,并保存页面html文档保存到本地,如果下载失败则抛出异常。并将下载过页面的路由添加到g_exist_urls
class CrawlerThread(threading.Thread):
def __init__(self,url,filename,tid):
threading.Thread.__init__(self)
self.filename=filename
self.url =url
self.tid=tid
def run(self):
try:
resp=urllib.request.urlopen(self.url)
html=resp.read()
with open('content/'+self.filename,'wb') as f:
f.write(html)
except Exception as e:
g_exist_urls.append(self.url)
g_failed_urls.append(self.url)
print(f'页面{self.url}下载失败!')
g_mutex.acquire()
g_urls.append(html)
g_exist_urls.append(self.url)
g_mutex.release()定义爬虫类:
对其进行构造,创建日志,download()函数创建线程,update_queque_url对连接的列表进行更新,get_url()根据bs4进行匹配获取连接,download_all()通过调用download()函数实现批量下载。spider作为一个入口函数进行爬取
class Crawler:
def __init__(self,name,domain,thread_number):
self.name=name
self.domain=domain
self.thread_number=thread_number
self.logfile=open('log.txt','w')
self.thread_pool=[]
self.url = 'http://'+domain
def spider(self):# 内容会随着爬虫的进行而更新
global g_queue_urls# 初始,队列中仅有一个url
g_queue_urls.append(self.url)# 爬取的深度
depth =0
print(f'爬虫{self.name}开始启动........')
while g_queue_urls:
depth +=1
print(f'当前爬取深度是{depth}')
self.logfile.write(f'URL:{g_queue_urls[0]}')
self.download_all() # 下载所有
self.update_queque_url() # 更新 url队列
self.logfile.write(f">>>Depth:{depth}")
count = 0
while count self.logfile.write(f"累计爬取{g_total_count}条,爬取是第{g_queue_urls[count]}个")
count+=1
def download_all(self):
global g_queue_urls
global g_total_count
i=0
while i < len(g_queue_urls):
j=0
while j g_total_count +=1
print(g_queue_urls[i+j])
thread_result=self.download(g_queue_urls[i+j],f"{g_total_count}.html",j)
if thread_result is not None:
print(f'线程{i+j}启动')
j +=1
i=i+j
for thread in self.thread_pool:
thread.join(25)
g_queue_urls=[]
def download(self,url,filename,tid):
print(url,filename,tid)
creawler_thread= CrawlerThread(url,filename,tid)
self.thread_pool.append(creawler_thread)
creawler_thread.start()
def update_queque_url(self):
global g_queue_urls
global g_exist_urls#已经爬过的url
new_urls=[]#新发现的url
for url_content in g_urls:
new_urls +=self.get_Url(url_content)# 从页面中提取新url
g_queue_urls=list(set(new_urls) -set(g_exist_urls)) # 去除重复的和已经爬过的
def get_Url(self,content):
'''
从网页源代码中提取url
'''
links =[] # 保存提取到的href
try:
soup =BeautifulSoup(content)
for link in soup.findAll('a'):
if link is not None and link.get('href') is not None:
if self.domain in link['href']:
# 如果link是本网站的绝对地址
links.append(link)
elif len(link['href']) >10 and 'http://' not in link['href']:
# 如果link是相对地址
links.append(self.url +link['href'])
except Exception as e:
print("fail to get url",e)
return links 主函数
主函数调用爬虫函数的spider()方法
if __name__=="__main__":
domain ="www.geyanw.com"
thread_number=10
name="geyan"
crawler =Crawler(name,domain,thread_number)
crawler.spider()关于python中怎么实现一个多线程爬虫就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
函数
爬虫
线程
环境
页面
内容
更新
地址
更多
深度
网页
队列
项目
帮助
不错
入口
兴趣
变量
小伙
小伙伴
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库技术理论知识总结
淘宝的服务器在哪
获取网络安全知识途径
数据库id自动增长到多少
网络技术的经验要求
网络安全学校西安
网络安全关口前移是什么意思
在网络安全防护中注重
服务器普通电源可以液冷吗
第五届上海网络安全
保障网络安全建设网络强国
小学网络安全自查小结
服务器项目端口多少比较安全
在哪里用代码创建数据库
智能照明服务器模块
开发板数据库连接
神奇宝贝复刻服务器大全
我的世界java粉丝服务器
app后台怎么搭建服务器
北京学软件开发三年制
质量可靠的屏幕共享软件开发
erd 数据库
2018全球数据库市场排行
软件开发人员劳务费怎么做账
游戏服务器宽带
有培训软件开发的培训班吗
保险软件开发有发展前途吗
中学生网络安全主题班会视频
数据库的安全实验目的
青浦区软件开发诚信合作