用Python爬虫抓取免费代理IP
點擊上方“程序員大咖”,選擇“置頂公眾號”
關鍵時刻,第一時間送達!
不知道大家有沒有遇到過“訪問頻率太高”這樣的網(wǎng)站提示,我們需要等待一段時間或者輸入一個驗證碼才能解封,但這樣的情況之后還是會出現(xiàn)。出現(xiàn)這個現(xiàn)象的原因就是我們所要爬取的網(wǎng)頁采取了反爬蟲的措施,比如當某個ip單位時間請求網(wǎng)頁次數(shù)過多時,服務器會拒絕服務,這種情況就是由于訪問頻率引起的封ip,這種情況靠解封不能很好的解決,所以我們就想到了偽裝本機ip去請求網(wǎng)頁,也就是我們今天要講的使用代理ip。
目前網(wǎng)上有許多代理ip,有免費的也有付費的,例如西刺代理等,免費的雖然不用花錢但有效的代理很少且不穩(wěn)定,付費的可能會好一點,不過今天我只爬取免費的代理并將檢測是否可用,將可用ip存入MongoDB,方便下次取出。
運行平臺:Windows
Python版本:Python3.6
IDE: Sublime Text
其他:Chrome瀏覽器
簡述流程為:
步驟1:了解requests代理如何使用
步驟2:從代理網(wǎng)頁爬取到ip和端口
步驟3:檢測爬取到的ip是否可用
步驟4:將爬取的可用代理存入MongoDB
步驟5:從存入可用ip的數(shù)據(jù)庫里隨機抽取一個ip,測試成功后返回
對于requests來說,代理的設置比較簡單,只需要傳入proxies參數(shù)即可。
不過需要注意的是,這里我是在本機安裝了抓包工具Fiddler,并用它在本地端口8888創(chuàng)建了一個HTTP代理服務(用Chrome插件SwitchyOmega),即代理服務為:127.0.0.1:8888,我們只要設置好這個代理,就可以成功將本機ip切換成代理軟件連接的服務器ip了。
import requests
proxy = '127.0.0.1:8888'
proxies = {
? ?'http':'http://' + proxy,
? ?'https':'http://' + proxy
}
try:
? ?response = requests.get('http://httpbin.org/get',proxies=proxies)
? ?print(response.text)
except requests.exceptions.ConnectionError as e:
? ?print('Error',e.args)
這里我是用來http://httpbin.org/get作為測試網(wǎng)站,我們訪問該網(wǎng)頁可以得到請求的有關信息,其中origin字段就是客戶端ip,我們可以根據(jù)返回的結(jié)果判斷代理是否成功。返回結(jié)果如下:
{
? ?"args":{},
? ?"headers":{
? ? ? ?"Accept":"*/*",
? ? ? ?"Accept-Encoding":"gzip, deflate",
? ? ? ?"Connection":"close",
? ? ? ?"Host":"httpbin.org",
? ? ? ?"User-Agent":"python-requests/2.18.4"
? ?},
? ?"origin":"xx.xxx.xxx.xxx",
? ?"url":"http://httpbin.org/get"
}
接下來我們便開始爬取代理IP,首先我們打開Chrome瀏覽器查看網(wǎng)頁,并找到ip和端口元素的信息。
可以看到,代理IP以表格存儲ip地址及其相關信息,所以我們用BeautifulSoup提取時很方便便能提取出相關信息,但是我們需要注意的是,爬取的ip很有可能出現(xiàn)重復的現(xiàn)象,尤其是我們同時爬取多個代理網(wǎng)頁又存儲到同一數(shù)組中時,所以我們可以使用集合來去除重復的ip。
將要爬取頁數(shù)的ip爬取好后存入數(shù)組,然后再對其中的ip逐一測試。
這里就用到了上面提到的requests設置代理的方法,我們使用http://httpbin.org/ip作為測試網(wǎng)站,它可以直接返回我們的ip地址,測試通過后再存入MomgoDB數(shù)據(jù)庫。
連接數(shù)據(jù)庫然后指定數(shù)據(jù)庫和集合,再將數(shù)據(jù)插入就OK了。
最后運行查看一下結(jié)果吧
運行了一段時間后,難得看到一連三個測試通過,趕緊截圖保存一下,事實上是,畢竟是免費代理,有效的還是很少的,并且存活時間確實很短,不過,爬取的量大,還是能找到可用的,我們只是用作練習的話,還是勉強夠用的。現(xiàn)在看看數(shù)據(jù)庫里存儲的吧。
因為爬取的頁數(shù)不多,加上有效ip也少,再加上我沒怎么爬,所以現(xiàn)在數(shù)據(jù)庫里的ip并不多,不過也算是將這些ip給存了下來。現(xiàn)在就來看看怎么隨機取出來吧。
由于擔心放入數(shù)據(jù)庫一段時間后ip會失效,所以取出前我重新進行了一次測試,如果成功再返回ip,不成功的話就直接將其移出數(shù)據(jù)庫。
這樣我們需要使用代理的時候,就能通過數(shù)據(jù)庫隨時取出來了。
總的代碼如下:
import random
import requests
import time
import pymongo
from bs4 import BeautifulSoup
# 爬取代理的URL地址,選擇的是西刺代理
url_ip = "http://www.xicidaili.com/nt/"
# 設定等待時間
set_timeout = 5
# 爬取代理的頁數(shù),2表示爬取2頁的ip地址
num = 2
# 代理的使用次數(shù)
count_time = 5
# 構(gòu)造headers
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'}
# 測試ip的URL
url_for_test = 'http://httpbin.org/ip'
def scrawl_xici_ip(num):
? ?'''
? ?爬取代理ip地址
? ?''' ?
? ?ip_list = []
? ?for num_page in range(1,num):
? ? ? ?url = url_ip + str(num_page)
? ? ? ?response = requests.get(url,headers=headers)
? ? ? ?if response.status_code == 200:
? ? ? ? ? ?content = response.text
? ? ? ? ? ?soup = BeautifulSoup(content,'lxml')
? ? ? ? ? ?trs = soup.find_all('tr')
? ? ? ? ? ?for i in range(1,len(trs)):
? ? ? ? ? ? ? ?tr = trs[i]
? ? ? ? ? ? ? ?tds = tr.find_all('td') ? ? ?
? ? ? ? ? ? ? ?ip_item = tds[1].text + ':' + tds[2].text
? ? ? ? ? ? ? ?# print(ip_item)
? ? ? ? ? ? ? ?ip_list.append(ip_item)
? ? ? ? ? ? ? ?ip_set = set(ip_list) # 去掉可能重復的ip
? ? ? ? ? ? ? ?ip_list = list(ip_set)
? ? ? ? ? ?time.sleep(count_time) # 等待5秒
? ?return ip_list
def ip_test(url_for_test,ip_info):
? ?'''
? ?測試爬取到的ip,測試成功則存入MongoDB
? ?'''
? ?for ip_for_test in ip_info:
? ? ? ?# 設置代理
? ? ? ?proxies = {
? ? ? ? ? ?'http': 'http://' + ip_for_test,
? ? ? ? ? ?'https': 'http://' + ip_for_test,
? ? ? ? ? ?}
? ? ? ?print(proxies)
? ? ? ?try:
? ? ? ? ? ?response = requests.get(url_for_test,headers=headers,proxies=proxies,timeout=10)
? ? ? ? ? ?if response.status_code == 200:
? ? ? ? ? ? ? ?ip = {'ip':ip_for_test}
? ? ? ? ? ? ? ?print(response.text)
? ? ? ? ? ? ? ?print('測試通過')
? ? ? ? ? ? ? ?write_to_MongoDB(ip) ? ?
? ? ? ?except Exception as e:
? ? ? ? ? ?print(e)
? ? ? ? ? ?continue
def write_to_MongoDB(proxies):
? ?'''
? ?將測試通過的ip存入MongoDB
? ?'''
? ?client = pymongo.MongoClient(host='localhost',port=27017)
? ?db = client.PROXY
? ?collection = db.proxies
? ?result = collection.insert(proxies)
? ?print(result)
? ?print('存儲MongoDB成功')
def get_random_ip():
? ?'''
? ?隨機取出一個ip
? ?'''
? ?client = pymongo.MongoClient(host='localhost',port=27017)
? ?db = client.PROXY
? ?collection = db.proxies
? ?items = collection.find()
? ?length = items.count()
? ?ind = random.randint(0,length-1)
? ?useful_proxy = items[ind]['ip'].replace(' ','')
? ?proxy = {
? ? ? ?'http': 'http://' + useful_proxy,
? ? ? ?'https': 'http://' + useful_proxy,
? ? ? ?} ?
? ?response = requests.get(url_for_test,headers=headers,proxies=proxy,timeout=10)
? ?if response.status_code == 200:
? ? ? ?return useful_proxy
? ?else:
? ? ? ?print('此{ip}已失效'.format(useful_proxy))
? ? ? ?collection.remove(useful_proxy)
? ? ? ?print('已經(jīng)從MongoDB移除')
? ? ? ?get_random_ip()
def main():
? ?ip_info = []
? ?ip_info = scrawl_xici_ip(2)
? ?sucess_proxy = ip_test(url_for_test,ip_info)
? ?finally_ip = get_random_ip()
? ?print('取出的ip為:' + finally_ip)
if __name__ == '__main__':
? ?main()
zhihu.com/people/hdmi-blog
程序員大咖整理發(fā)布,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)
【點擊成為源碼大神】
總結(jié)
以上是生活随笔為你收集整理的用Python爬虫抓取免费代理IP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 路由策略概述
- 下一篇: 结算计算机设备维护费的请示,关于购买计算