Python網絡爬蟲筆記(二):鏈接爬蟲和下載限速


(一)代碼1(link_crawler()和get_links()實現鏈接爬蟲)

 1 import urllib.request as ure
 2 import re
 3 import urllib.parse
 4 from delayed import WaitFor
 5 #下載網頁並返回HTML(動態加載的部分下載不了)
 6 def download(url,user_agent='Socrates',num=2):
 7     print('下載:'+url)
 8     #設置用戶代理
 9     headers = {'user_agent':user_agent}
10     request = ure.Request(url,headers=headers)
11     try:
12         #下載網頁
13         html = ure.urlopen(request).read()
14     except ure.URLError as e:
15         print('下載失敗'+e.reason)
16         html=None
17         if num>0:
18             #遇到5XX錯誤時,遞歸調用自身重試下載,最多重復2次
19             if hasattr(e,'code') and 500<=e.code<600:
20                 return download(url,num-1)
21     return html
22 #seed_url傳入一個url
23 #link_regex傳入一個正則表達式
24 #函數功能:提取和link_regex匹配的所有網頁鏈接並下載
25 def link_crawler(seed_url, link_regex):
26     html = download(seed_url)
27     crawl_queue = []
28     #迭代get_links()返回的列表,將匹配正則表達式link_regex的鏈接添加到列表中
29     for link in get_links(html):
30         if re.match(link_regex, link):
31             #拼接https://www.cnblogs.com/ 和 /cate/...
32             link = urllib.parse.urljoin(seed_url, link)
33             #不在列表中才添加
34             if link not in crawl_queue:
35                 crawl_queue.append(link)
36     #調用WaitFor的wait()函數,下載限速,間隔小於2秒則等待,直到時間等於2秒才繼續下載(大於則直接繼續下載)
37     waitFor = WaitFor(2)
38     #下載crawl_queue中的所有網頁
39     while crawl_queue:
40         #刪除列表末尾的數據
41         url = crawl_queue.pop()
42         waitFor.wait(url)
43         download(url)
44 #傳入html對象,以列表形式返回所有鏈接
45 def get_links(html):
46     #使用正則表達式提取html中所有網頁鏈接
47     webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']',re.IGNORECASE)
48     html = html.decode('utf-8')
49     # 以列表形式返回所有網頁鏈接
50     return webpage_regex.findall(html)
51 
52 link_crawler('https://www.cnblogs.com/','/cate/.*')

(二)delayed.py(實現下載限速的類)

 1 import urllib.parse
 2 import datetime
 3 import time
 4 class WaitFor():
 5 
 6     def __init__(self,delay):
 7         #delay:希望延遲多長時間(wait()中的處理是以秒為單位)
 8         self.delay = delay
 9         #用來存放上次下載時間
10         self.domains = dict()
11 
12     def wait(self,url):
13         #獲取url netloc屬性的值(即www.cnblogs.com,// 和第一個 /之間的內容)
14         domain = urllib.parse.urlparse(url).netloc
15         #存在鍵值為domain的數據返回value值,否則返回None
16         last_down = self.domains.get(domain)
17         if self.delay >0 and last_down is not None:
18             #  希望延遲時間 - (當前時間-上次下載時間),seconds時間間隔以秒為單位顯示
19             sleep_sec = self.delay-(datetime.datetime.now()-last_down).seconds
20             if sleep_sec > 0:
21                 time.sleep(sleep_sec)
22         #將當前時間添加到domains中
23         self.domains[domain] = datetime.datetime.now()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM