1. 程式人生 > >Python爬蟲設定動態代理(線上獲取)

Python爬蟲設定動態代理(線上獲取)

問題

在寫爬蟲的早期,一些小的練手專案,並不會涉及到IP的問題,用預設的網路爬一下就OK了。但是一旦面臨較大的資料量,較多條目的資料,意味著更多的請求。就有了自己預設IP被封的可能性。一個合格的網站為了防止伺服器負載過大,也應該設定這樣的機制來限制頻繁請求。
那麼我們寫爬蟲的人該如何處理這種情況呢?

解決

為了防止一個IP訪問過於頻繁而造成的的拒絕訪問,治標的方法是,在求請訪問的時候設定一定的時間間隔


import time
......
time.sleep(10)
....

這種方法對於很多的網站已經是足夠對付了,但是仍然有一定的風險,尤其是資料量很大的時候。
治本的方法是,設定動態代理


直接來看程式碼:

    def get_ip_list(self):
        print("正在獲取代理列表...")
        url = 'http://www.xicidaili.com/nn/'
        html = requests.get(url=url, headers=self.headers).text
        soup = BeautifulSoup(html, 'lxml')
        ips = soup.find(id='ip_list').find_all('tr')
        ip_list = []
        for i in range(1, len(ips)):
            ip_info = ips[i]
            tds = ip_info.find_all('td')
            ip_list.append(tds[1].text + ':' + tds[2].text)
        print("代理列表抓取成功.")
        return ip_list

    def get_random_ip(self,ip_list):
        print("正在設定隨機代理...")
        proxy_list = []
        for ip in ip_list:
            proxy_list.append('http://' + ip)
        proxy_ip = random.choice(proxy_list)
        proxies = {'http': proxy_ip}
        print("代理設定成功.")
        return proxies

主要由兩個函式組成,一個是從 http://www.xicidaili.com/nn/ 抓取代理IP的函式,返回得到IP地址和埠號組成的列表。第二個函式是從第一個函式得到的列表中隨機選取代理IP,並組裝成proxies字典格式,然後返回。

使用方式:

resp = requests.get(key.uri, headers = self.headers, proxies=proxies)

在程式中可以設定定點,比如每採集固定個數個專案後就更換一次IP。
get_ip_list()函式實際上只採集了一頁的IP,但是隻要配合好sleep()使用,已經可以應對絕大多數情況,而且一頁的IP其實數量也相當不少了呢~~