天天看點

網頁爬取系列(一)爬取網頁資料的一些小技巧

1、檢查 robots.txt

import urllib.robotparser as rparser
def isCheckRobots(user_agent,robots_url, url):
    '''檢查robots.txt'''

    rp = rparser.RobotFileParser()
    rp.set_url(robots_url)
    rp.read()
    return rp.can_fetch("*", url)
           

2、設定使用者代理

其實就是重新設定一下 user_agent

3、重試下載下傳

伺服器傳回碼為 4xx 時說明 請求 存在錯誤,

而傳回碼為 5xx 時說明服務端存在問題,我們隻要確定傳回碼在 5xx 時重試下載下傳

def getHtmlText(url, encoding = 'utf-8', user_agent = 'Mozilla/5.0', new_time_out = , num_retries = , isNeedCheckRobots = False, robots_url = None):
    '''擷取資訊'''  

    if isNeedCheckRobots:
        if isCheckRobots(user_agent, robots_url, url) is False:
            return 'robots.txt 不允許'
    try:
        headers = {'user_agent' : user_agent}
        r = requests.get(url, timeout = new_time_out, headers = headers)
        r.encoding = encoding
        r.raise_for_status()
        return r.text
    except:    
        # 伺服器傳回碼為 5xx 時,則說明錯誤發生在伺服器端,以下代碼支援重試下載下傳
        if r.status_code >=  and r.status_code <=  and num_retries > :
            return  getHtmlText(url, encoding, new_time_out, num_retries - )
        return '下載下傳網頁失敗'   
           

4、下載下傳限速

在兩次相同域名的 url 請求下加入延遲,以免爬取網站的速度過快被伺服器封禁

import time
import datetime
from urllib import parse

class Throttle():
    '''在同個域名請求加入延時'''

    def __init__(self, delay):
        # 延時時間
        self.delay = delay
        # 最後一次通路域名的時間戳
        self.domain = {}

    def wait(self, url):
        domain = parse.urlparse(url).netloc
        last_visit = self.domain.get(domain)

        if self.delay >  and last_visit is not None:
            sleep_secs = self.delay - (datetime.datetime.now() - last_visit).seconds
            if sleep_secs > :
                time.sleep(sleep_secs)
        self.domain[domain] = datetime.datetime.now()