上一节说讲到了基础的网络爬虫,全国300多个城市,每个城市爬取需要3分钟,总耗时要900多分钟,就是十多个小时,效率很低。这一次,笔者会讲解多线程网络爬虫的操作流程,原来10多个小时的任务,在多线程的运作下,16分钟就能搞定。
废话不多说,上代码:
#导入库
import requests
import re
import os
from multiprocessing.dummy import Pool as ThreadPool
#这个模块的作用是抓取网页源代码,也就是你在浏览器中单击鼠标右键中查看源代码出现的内容
def getHTMLText(url):
try:
kv={'user-agent':'Mozilla/5.0'} #模拟头文件,相当于用假冒的身份证骗过网站的门卫
r = requests.get(url, timeout=30,headers=kv) #抓取网页源代码
r.raise_for_status() #查看状态
r.encoding = r.apparent_encoding #自动识别并更改编码方式
return r.text #爬下来的源代码保存在内存中的r.text中
except:
return ""
#这个模块的作用是通过榛果民宿首页源代码,获取全国所有城市的名字,为后面分城市抓取数据做铺垫
def getLoc(lst,page):
try:
r=getHTMLText(page) #抓取首页源代码
elt=re.findall('<li><a href="/(.*?)/" class="btn btn-default">',r) #找到所有城市对应的拼音简称
clt=re.findall('class="btn btn-default">(.*?)</a></li>',r) #找到所有城市对应的中文简称
#将中英文简称填入lst表中,方便之后留用
for i in range(len(elt)):
eng=elt[i]
chn=clt[i]
lst.append([eng,chn])
except:
print("")
#页面解析,每个城市对应的源代码被抓取后,在这里进行解析
def parsePage(ilt, html):
try:
plt = re.findall('</i>([\d]*)</span>',html) #找到抓取源代码中的所有价格信息
alt = re.findall('<span class="room-prop">(.*?)</span></div><div',html) #找打抓取源代码中的所有位置区域信息
#将位置和价格信息导入到ilt表中
for i in range(len(plt)):
price = plt[i]
area = alt[i].split('</span><span class="room-prop">')[-1]
ilt.append([price , area])
except:
print("")
#将结果打印到屏幕上,以查看是否爬取成功
def printGoodsList(ilt):
tplt = "{:4}\t{:8}\t{:16}"
print(tplt.format("序号", "价格", "区域")) #画出表头
count = 0
for g in ilt: #将存储到ilt中的价格和区域数据逐行打印到屏幕上
count = count + 1
print(count),
print(g[0]),
print(g[1])
#并行爬取模块,将300个地址作为多线程元素,进行爬取。
def mufunc(lt):
loc = lt[0] #地址拼音
depth=60 #爬取深度
begin=20191021 #入住时间
end=20191022 #离店时间
start_url = 'https://www.zhenguo.com/' + loc + '/' #网址
infoList = [] #构造一个空表,用于保存信息
for i in range(depth): #一页一页地进行数据爬取
try:
i=i+1
url = start_url+"pn"+str(i)+"/?dateBegin="+str(begin)+"&dateEnd="+str(end) #最终网址
html = getHTMLText(url) #网址访问,爬取源代码
parsePage(infoList, html) #网址信息解析,提取价格和区域信息
except:
continue
printGoodsList(infoList) #将结果打印到屏幕上
f=open(lt[1]+'.txt','w') #将结果输出到本地文件中
for k in infoList:
for m in k:
m=m.encode('utf-8')
print>>f,m,
print>>f,'\n'
f.close()
#指挥官登场
def main():
page="https://www.zhenguo.com/" #首页网址,也称初始网址
lst=[] #用于保存城市中文和拼音信息的空表
getLoc(lst,page) #从首页获取所有城市的拼音和中文信息,保存至lst中
pool = ThreadPool(20) #设置并行的线程数,这里为20线程
pool.map(mufunc,[k for k in lst]) #启动每个线程,开始进行数据爬取
#启动指挥官
main()
接下来的事,你们千万别惊讶,你会发现你的cpu疯转,你的网速飞快,你屏幕上的信息飞速显示出来,不到16分钟,你的桌面上就会出现满满的300多个城市的榛果民宿文档。这,就是并行爬虫的魅力
接下来的事,你们千万别惊讶,你会发现你的cpu疯转,你的网速飞快,你屏幕上的信息飞速显示出来,不到16分钟,你的桌面上就会出现满满的300多个城市的榛果民宿文档。这,就是并行爬虫的魅力接下来的事,你们千万别惊讶,你会发现你的cpu疯转,你的网速飞快,你屏幕上的信息飞速显示出来,不到16分钟,你的桌面上就会出现满满的300多个城市的榛果民宿文档。这,就是并行爬虫的魅力接下来的事,你们千万别惊讶,你会发现你的cpu疯转,你的网速飞快,你屏幕上的信息飞速显示出来,不到16分钟,你的桌面上就会出现满满的300多个城市的榛果民宿文档。这,就是并行爬虫的魅力
视频请移步视频区观看
下面看结果:几秒钟,便生成了十几个文件,可见并行爬虫的效率之高。