爬蟲I號 :獲取免費代理伺服器&進行代理驗證
阿新 • • 發佈:2019-02-08
閒來無聊,正兒八經寫的個人第一Python小程式
------爬蟲I號:獲取免費代理伺服器&自動驗證
- 需求:
不要問我為什麼要用代理,有需求的自然明白。
- 知識點:
1.list的使用
2.file操作的使用
3.類的使用
4.requests 模組的使用,為了獲取西刺網站的頁面,也用於驗證代理IP是否有效;不喜歡用urllib
5.正則表示式的使用,為了爬網頁,也可以考慮用Beautifulsoup,看需求了
6.try, with等異常處理語句的使用
- 設計流程:
設計思想很簡單,細分以下幾個步驟:
1.初始化類,配置Proxy 資源網站URL,用於驗證Proxy IP的URL,存取Proxy IP的檔案
2.獲取Proxy資源網站內容
3.通過正則表示式爬 IP和Port資源,蒐集成Proxy_all_list
4.驗證Proxy_all_list中的每一個IP,並記錄有效IP
話不多說,直接上Code,有詳細註解。
#coding=utf-8 #<<<Web crawler I>>> : Get & Verify Proxy , written by HuangYu 20180814 import re #正則表示式庫,用來匹配網頁元素 import socket #用於設定網路連線的相關屬性 import sys import requests #用於進行HTTP的相關處理,urllib庫用起來還是比較煩的,requests用起來so easy import logging #log相關功能,不能總是用print那麼low class ProxyProber: def __init__(self): #類的初始化函式,在類中的函式都有個self引數,其實可以理解為這個類的物件 self.file_proxy_all_list = "proxy_all.txt" #儲存 免費代理伺服器網站 爬下來的所有代理IP self.file_proxy_valid_list = "proxy_valid.txt" #儲存 通過驗證可用的 代理IP self.proxy_resource = "http://www.xicidaili.com/wn/" #用於爬取代理資訊的網站 self.verify_url = "http://www.baidu.com/" #用於驗證Proxy IP的網站 #要為http報文分配header欄位,否則很多頁面無法獲取 self.http_headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0', 'Accept-Encoding': 'gzip, deflate' } #配置log資訊儲存的位置 logging.basicConfig(filename='./proxy_debug.log', filemode="w", level=logging.DEBUG) #3秒內沒有開啟web頁面,就放棄等待,防止死等,不管哪種語言,都要防範網路阻塞造成程式響應遲滯,CPU經常因此被冤枉 socket.setdefaulttimeout(3) def getWebInfoByRe(self, context): #用於通過正則表示式取頁面中的關鍵資訊,context是頁面內容 ip_port_list = [] get_ip_re = re.compile("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") #取頁面中所有格式為“數字.數字.數字.數字”的資料存入IP列表 ip_list = get_ip_re.findall(str(context)) get_port_raw_re = re.compile("<td>\d{2,5}</td>") #取頁面中所有的格式為“<td>數字</td>”的資料存入Port草稿列表 port_list_raw = get_port_raw_re.findall(str(context)) get_port_re = re.compile("\d{5}|\d{4}|\d{2}") #取上一批資料中所有的 “數字” 存入Port列表 port_list = get_port_re.findall(str(port_list_raw)) if ip_list is None: return None if port_list is None: return None if len(ip_list)!=len(port_list): #理論上IP和Port應該成對出現,沒有再做太多的容錯處理 return None for index in range(len(ip_list)): #將IP和Port列表中的資料一一匹配成“IP:Port”的格式存入list ip_port_list.append(str(ip_list[index]) + ":" + str(port_list[index])) return ip_port_list def getProxyResource(self,url): #獲取代理伺服器網站資訊,並儲存 if len(url)==0: print("Url is null!") return requests.adapters.DEFAULT_RETRIES = 5 proxy_resource_request = requests.session() proxy_resource_request.keep_alive = False #獲取url內容 try: proxy_resource_result =proxy_resource_request.get(url, headers=self.http_headers) except: print("proxy_resource can't get!!!") return #頁面內容存入log檔案,爬頁面的時候,都要獲取頁面原始碼分析其中的關鍵元素;當然,你也可以使用瀏覽器的debug元件分析 logging.debug(proxy_resource_result.content) #開始提取頁面中的IP和Port列表 proxy_list = self.getWebInfoByRe(proxy_resource_result.content) #統計list元素個數 print(len(proxy_list)) if len(proxy_list)==0: print("Get Proxy fail!") return #將list中所有資訊寫入proxy_all.txt fd_proxy_all = open(self.file_proxy_all_list, 'w') #with as 語法的使用,可以省去close檔案的過程 with open(self.file_proxy_all_list, 'w') as fd_proxy_all: for ip_port in proxy_list: fd_proxy_all.write(str(ip_port) + "\n") def verifyProxy(self): #從proxy_all.txt獲取所有Proxy IP進行驗證,將有效的IP存入proxy_valid.txt index = 0 requests.adapters.DEFAULT_RETRIES = 5 test_proxy = requests.session() test_proxy.keep_alive = False #將proxy_all.txt中所有資訊讀到ip_port_list中, with open(self.file_proxy_all_list, 'r') as fd_proxy_all: ip_port_list = fd_proxy_all.readlines()#讀取全部內容 #建立一個新的proxy_valid.txt try: fd_proxy_valid = open(self.file_proxy_valid_list,'w') except: print ("proxy_valid.txt open is fail!") return finally: fd_proxy_valid.close() for ip_port in ip_port_list: proxy_url = {'http':'http://' + ip_port.strip('\n')} #request.get資訊中需要填寫proxies欄位,欄位的format={'http':'http://ip:port'} #因為讀回的資訊每一行都有"\n",所以需要用.strip過濾掉"\n" index+=1 print(str(index)) try: #通過request.get獲取驗證頁面,timeout用於防止 傻等,畢竟要驗證一堆IP test_page =test_proxy.get(self.verify_url, headers=self.http_headers, proxies=proxy_url, timeout=(2,3)) except: #如果獲取頁面異常,進入這兒,再處理下一個IP print("Invaild Proxy : " + ip_port.strip('\n')) continue #獲取正常的頁面返回碼一般都是200,不是的話繼續處理下一個IP if test_page.status_code!=200: print("Invaild Proxy : " + ip_port.strip('\n')) continue #能用的IP存入proxy_valid.txt print("*********Vaild Proxy : " + ip_port.strip('\n')) with open(self.file_proxy_valid_list, 'a') as fd_proxy_valid: fd_proxy_valid.write(ip_port.strip('\n') + " "+ str(test_page.elapsed.total_seconds()) + "\n") if __name__ == "__main__": prober_handler = ProxyProber() #prober_handler.getProxyResource(sys.argv[1]) #prober_handler.getProxyResource("http://www.xicidaili.com/wn/") prober_handler.getProxyResource(prober_handler.proxy_resource) #物件名=self,看到這就可以理解類裡的self是什麼了。 prober_handler.verifyProxy()