
文章目錄
- 前言
- 資料集
- 知識儲備
- 正主:Python大并發爬蟲
- 1.0版本:原始版
- 2.0版本,加上時間處理、快取
- 批量下載
- 圖片批量下載
- 批量音頻下載
- 視頻下載
- 開多少執行緒/行程合適?
前言
emmmm,又到了單數篇,
不知道為什么,我居然會覺得,這個系列,單數篇必是精品,雙數篇基本劃水,,
好,廢話不多說,本篇我們進入了大并發時代,看看我們的大并發爬蟲,
資料集
什么是大并發?幾千個量?幾萬個量?幾十萬個?好意思嗎?
這波我找了近兩萬個資料集(好吧,小是小了點,本來有個一百萬網址的資料集,但是大部分都是國外網址,爬不來)
太大了放不下,大家掃一下左邊側欄的那個二維碼,回復“爬蟲大并發”拿一下資料集,我準備了csv格式、Excel格式、還有最原始的資料集以及清洗代碼,看你喜歡哪種了,
知識儲備
大并發編程嘛,不是跟你開玩笑的啊,
Python都封裝的很好了,但是你要是僅僅滿足于Python的封裝呢,那你跳過這一段吧,
在我這里,要給你知其然知其所以然,
東西太多了,接下來每篇都基本是萬字長文,做好準備了嗎?

都是我寫的,看起來也不會無聊
行程·全家桶(這篇還被CSDN的公眾號選中了)
Posix執行緒 它們那一大家子事兒,要覺得好你就收藏進被窩里慢慢看 (1)
Posix執行緒 它們那一大家子事兒,要覺得好你就收藏進被窩里慢慢看 (2)
【C++】勉強能看的執行緒池詳解
Python爬蟲自學系列(三)(快取系列,redis的鏈接太多了,就用這篇吧)
訊息佇列:解耦、異步、削峰,現有MQ對比以及新手入門該如何選擇MQ?
這些東西要是都用文字堆上來,那好像有點喧賓奪主了
正主:Python大并發爬蟲
1.0版本:原始版
哪里有一蹴而就的好事兒啊,先來個最原始的版本吧,
import threadpool
import requests
def get_data():
op = open('CSDN_xml.txt')
s = op.read()
s = s.strip().split(' ')
datalist = s[::4]
return datalist
def outdata(url):
try:
print('succeed'+url)
requests.get(url)
except:
print('failed'+url)
def Thread_Pool(outdata,datalist = None,Thread_num = 5):
'''
執行緒池操作,創建執行緒池、規定執行緒池執行任務、將任務放入執行緒池中、收工
:param outdata: 函式指標,執行緒池執行的任務
:param datalist: 給前面的函式指標傳入的引數串列
:param Thread_num: 初始化執行緒數
:return: 暫無
'''
pool = threadpool.ThreadPool(Thread_num) # 創建Thread_num個執行緒
tasks = threadpool.makeRequests(outdata, datalist) # 規定執行緒執行的任務
# outdata是函式名,datalist是一個引數串列,執行緒池會依次提取datalist中的引數引入到函式中來執行函式,所以引數串列的長度也就是執行緒池所要執行的任務數量,
[pool.putRequest(req) for req in tasks] # 將將要執行的任務放入執行緒池中
pool.wait() # 等待所有子執行緒執行完之后退出
datalist = get_data()
Thread_Pool(outdata,datalist=datalist)
當有 URL 可爬取時,上面代碼中的回圈會不斷創建執行緒,直到達到執行緒池的最大值,在爬取程序中,如果當前佇列中沒有更多可以爬取的 URL時,執行緒會提前停止,
2.0版本,加上時間處理、快取
這里的時間處理可不是說睡眠時間,還有計時器,因為后面我們要進行不同版本的測驗嘛,
快取嘛,雖然不會那啥,但是還是加一下吧,
改動的地方:
1、把那些零零碎碎的指令放一塊兒了
def main():
start = time.perf_counter()
requests_cache.install_cache('bf_cache')
requests_cache.clear()
datalist = get_data()
Thread_Pool(outdata,datalist=datalist)
delta = time.perf_counter() - start
print('共用時:'+ str(delta))
2、函式指標中的修改:
def outdata(url):
try:
# print('succeed'+url)
res = requests.get(url)
if res.from_cache:
print('從快取中獲取:'+url)
except:
print('failed'+url)
# finally:
# time.sleep(2)
這要真兩秒下去,那怕是沒了,,
然后上面我調成1000了,兩萬太久了,,

我覺得是不是假了點啊,我等了這么久,跟我說就一分鐘!!
開十個執行緒看看:Thread_Pool(outdata,datalist=datalist[:1000],Thread_num = 10)
看看效果是否對折了,

好,可以看到,花了43秒,大概折了四分之一,
那是不是說執行緒越多越好呢?是不是開足夠多的執行緒,就可以在一秒內解決戰斗呢?
兄弟,前面的鏈接看了就不會有這個想法了,開執行緒,是要耗費資源的,雖然沒有行程耗費的那么大,而且管理執行緒也需要資源和時間的,何況這還是Python,
我剛剛測驗了20個執行緒,花了40秒,多開無益,
先到2.0版本吧,如果日后發現有新的需求再加,
批量下載
圖片批量下載
上邊那個框架其實已經差不多了,只要改一下資料源,然后函式指標里面微調一下就好啦,
def outdata(data):
'''
這是一個處理資料的函式,即將被送入執行緒池
:param data: 這是一個字典,以圖片名為鍵,圖片鏈接為值
:return: 無
'''
item_list = data.items()
for item in item_list:
try:
res = requests.get(item[1])
if res.from_cache :
print('從快取中獲取:'+item[1])
else:
f = open(item[0],'wb+')
f.write(res.content)
except:
print('failed'+item[1])
# finally:
# time.sleep(2)
批量音頻下載
其實吧,這里就改一下資料源就行了,其他都可以復用,
那這個資料源哪里找呢?
打開酷狗,或者其他音樂軟體,然后找后綴為音樂的(mp3啥的),

有看到不?
我不知道是網頁版的酷狗沒有VIP限制還是說因為我本身是有VIP的,我找了首APP上聽要VIP才給聽的歌,也可以直接聽,
視頻下載
視頻也差不多改一下資料來源的函式就行,不過視頻要注意那個網址弧沒有后綴,所以可以用模塊定位法(Xpath那一套)找到鏈接位置,
然后手動添加上后綴,就寫成mp4就好啦,
開多少執行緒/行程合適?
看一下人家的測驗資料吧:

本來想講講多行程的,但是我本身不是很喜歡拿行程來做這種大量并發的,
行程,拿來做集群分布式就好了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/251779.html
標籤:python
上一篇:Scrapy爬蟲框架的決議與實體(中國大學MOOC)
下一篇:python常用標準庫總結
