python多程序爬蟲卡住 Python多程序爬蟲

2021-10-19 02:21:22 字數 4251 閱讀 9496

匯入第3方庫:

from bs4 import beautifulsoup

from spider.extra import utils

from multiprocessing import process,value,joinablequeue,manager,pool

import threading

import argparse

from fake_useragent import useragent

import time,random,requests

定義爬蟲程序:

class spiderwork(process):

def __init__(self,q,res_q,complete_num,begin_time,proxy_list,proxytime):

super().__init__()

self.q = q

self.res_q = res_q

self.complete_num = complete_num

self.proxy_list = proxy_list

self.init_time = time.time()

self.begin_time = begin_time

self.proxytime = proxytime

def run(self):

while true:

url = self.q.get()

self.crawl_url(url)

self.q.task_done()

def crawl_url(self,url):

if time.time() - self.init_time > self.proxytime:

self.init_time = time.time()

self.proxy_list = utils.get_proxy_every_15_min()

soup = beautifulsoup(self.gethtmltext(url), 'html.parser')

try:

down_href = soup.select('#down_url > li:nth-child(2) > a')[0]

self.res_q.put((url, down_href["href"]))

self.complete_num.value += 1

if self.complete_num.value % 40 == 0:

time_span = time.time() - self.begin_time

print("------完成數量:%d,用時:%d秒------\n" % (self.complete_num.value, time_span))

except:

def gethtmltext(self,url):

retry_time = 0

res = ''

while true:

proxy = random.choice(self.proxy_list)

ua = useragent(use_cache_server=false)

try:

headers = ,url:,當前重試次數----')

res = r.text

break

except:

retry_time += 1

print(f'----**失效,url:,當前重試次數----')

if retry_time > 20:

print(f'----url:,當前重試次數大於20,爬取失敗----')

break

return res

定義寫程序,用來訪問爬到的結果:

def writefile_job(done_md5_file,res_q):

while true:

res = res_q.get()

print(f'------')

with open('exe_result.txt', 'a', encoding='utf-8') as fw:

fw.write(res[1]+'\n')

with open(done_md5_file, 'a', encoding='utf-8') as fw:

fw.write(res[0]+'\n')

res_q.task_done()

程式入口**,接受3個引數:

file-儲存待爬取url的文字路徑,格式一行乙個url

proxytime-**更新時間,使用**防止被封

cpunum-開啟的程序個數,預設是cpu的核心數

parser = argparse.argumentparser(description='crawl virustotal')

parser.add_argument('--file','-f',required=true)

parser.add_argument('--proxytime','-p',type=int,default=900)

parser.add_argument('--cpunum','-c',type=int,default=os.cpu_count())

args = parser.parse_args()

cpu_num = args.cpunum if args.cpunum < os.cpu_count() else os.cpu_count()

url_file = args.file

載入待爬取的所有url:

urls =

with open(url_file, 'r', encoding='utf-8') as fr:

for line in fr.readlines():

line = line.replace("\n", "")

if len(line)>0:

讀取已完成的url,計算待爬取的url,用來處理程式中斷後,可以從中斷處繼續爬取:

done_url_file = os.path.splitext(url_file)[0]+ '_done.txt'

done_url = #讀取已爬取完成的md5

if os.path.isfile(done_url_file):

with open(done_url_file, 'r') as fr:

for line in fr.readlines():

line = line.replace("\n", "")

if len(line) > 0:

#計算未爬取的md5

undone_url = list(set(urls) - set(done_url))

print(f'檢測到已完成的url有:個')

print(f'重新計算需要爬取的url個數,為:個')

將待爬取的url放入佇列,多程序從佇列中取url:

q = joinablequeue()

for url in undone_url:

q.put(url)

獲取**,新建乙個佇列用來儲存爬取結果:

proxy_list = utils.get_proxy_every_15_min()

begin_time = time.time()

res_q = joinablequeue()

開啟多個程序,從佇列讀取url爬取,同時開啟乙個執行緒,一直從儲存結果的返回佇列讀出資料,並儲存:

with manager() as mg:

complete_num = value('i', 0)

for i in range(cpu_num):

p = spiderwork(q,res_q,complete_num,begin_time,proxy_list,args.proxytime)

p.daemon = true #主程序結束,程序結果,故設為守護程序

p.start()

wr_td = threading.thread(target=writefile_job, args=(done_url_file,res_q,))

wr_td.setdaemon(true) #主程序結束,執行緒結果,故設為守護程序

wr_td.start()

q.join() #等待佇列中url全部爬取完成

res_q.join() #等待返回佇列中結果全部處理完成

end_time = time.time()

print(f'原始urls:')

print(f'完成數量:')

print(f'用時:')

python多程序卡住 python多程序假死

結論 python多程序間用queue通訊時,如果子程序操作queue滿了或者內容比較大的情況下,該子程序會阻塞等待取走queue內容 如果queue資料量比較少,不會等待 如果呼叫join,主程序將處於等待,等待子程序結束,造成死鎖 解決方式 在呼叫join前,及時把queue的資料取出,而且qu...

多程序爬蟲

1.多程序爬貓眼電影 下圖是爬去後的結果 在寫爬蟲的時候,資料量大的時候,所需要的時間就會很長,所以今天就來說多程序爬資料,有興趣的可以執行下面的 coding utf 8 import sys reload sys sys.setdefaultencoding utf 8 import reque...

Python 學習筆記 多程序爬蟲

前段時間學習了多執行緒,但在實際的情況中對於多執行緒的速度實在不滿意,所以今天就來學學多程序分布式爬蟲,在這裡感謝莫煩的python教程。在講述多程序之前,先來回顧一下之前學習的多執行緒。對於多執行緒可以簡單的理解成運輸快遞的貨車,雖然在整個運輸快遞的途中有很多貨車參與運輸,但快遞到你手中的時間並不...