最近正在筹划爬取一些大型网站的数据,因为预想到这些网站的反爬措施比较多。首先筹备建立自己的一个代理池,手工测试了一下国内的开源的免费代理,发现西刺代理的可用率比较高,今天就写一个爬虫,爬取西刺代理可用的代理池。
步骤是:
1.抓取西刺代理的网页文件
2.通过正则解析代理
3.通过访问baidu测试可用的代理
4.讲可用代理写入文本文件中
5.结合花刺代理使用
1 # -*- coding: utf-8 -*- 2 import urllib.request 3 import urllib.parse 4 import re 5 6 def handle_request(url,page): 7 #拼接成指定页面的url 8 url = url + str(page) 9 print(url) 10 headers={ 11 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 12 } 13 14 #生成请求对象 15 request = urllib.request.Request(url=url,headers=headers) 16 return request 17 18 def parse_content(content): 19 20 pattern = re.compile(r'<td>((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))</td>.*?<td>(d+)</td>.*?<td>.*?</td>.*?<td>(.*?)</td>',re.S) 21 #通过正则处理,通过分组符号()得到一组元组的列表,元组中第一个元素是IP,第二个元素是端口,第三个元素室协议 22 lt = pattern.findall(content) 23 24 return lt 25 26 def test_agent(agent): 27 #使用百度测试代理 28 url = "http://www.baidu.com/s?wd=ip" 29 headers={ 30 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', 31 } 32 #拼接ip_port字段 33 ip_port = agent[0]+':'+agent[1] 34 #创建handler对象 35 handler = urllib.request.ProxyHandler({agent[2]:ip_port}) 36 #创建opener对象 37 print("zheli") 38 opener = urllib.request.build_opener(handler) 39 #生成请求对象 40 try: 41 request = urllib.request.Request(url=url,headers=headers) 42 #发送请求,得到返回状态 43 try : 44 response = opener.open(request,timeout=10) 45 if response.getcode() == 200: 46 print("ip可用") 47 return True 48 else: 49 print("ip不可用") 50 return False 51 except Exception as e: 52 print(e) 53 except Exception as e: 54 print(e) 55 56 57 58 def main(): 59 url = 'https://www.xicidaili.com/nn/' 60 start_page = int(input("请输入起始页:")) 61 end_page = int(input("请输入结束页;")) 62 for page in (start_page,end_page+1): 63 #获取请求对象 64 request = handle_request(url,page) 65 66 #获取网页文件 67 content = urllib.request.urlopen(request,timeout=10).read().decode() 68 #解析文件 69 lt = parse_content(content) 70 for agent in lt : 71 #测试代理是否能够被调用 72 if test_agent(agent) != False: 73 #第一个元素是IP 74 ip = agent[0] 75 #第二个元素是端口 76 port = agent[1] 77 #第三个元素是协议 78 protocal= agent[2] 79 #拼接成一行的字符串 80 string = '%s %s %s ' %(ip,port,protocal) 81 #将字符串追加写到文件中 82 with open("ip_pool.txt","a") as fp: 83 fp.write(string) 84 85 86 #入口 87 if __name__ =='__main__': 88 main() 89