前言
上次把更改user-agent的教程给写了,结果发现自己把所有的user-agent拼成了user-again【吓哭】
英语不好害死人啊
这次的教程为了反那个ip代理网站的爬,所以用上了上次的headers信息更换,下面源码里面所有的headers都用到了自动更换头信息,定义的头信息的语句写在每一个requests.get里面的
上期文章的传送门
正文
遇到那些买了至尊JS反爬的dalao阔站来说哟
就应该用至尊的方法来对付他们
当当当当~代理IP高大上
就是相当于在浏览器里面加了一个VPN的感觉
0x01 准备
需要用到的库:
- import requests #用来请求网页
- import random #随机数用来跑裤,可以自定义
- import time #有些阔站会检测时间,就随手加上了,但其实也没什么用因为时间控制我没写【根本不是因为我懒】
- import re 正则表达式用来提取ip
- import UserAgent2 #这个是我自己写的基于头信息的反追踪
- from bs4 import BeautifulSoup #处理网页信息,如果用了re就没有必要加,但是我Python3下载的时候不知道为什么把正则模块给弄没了......
除此之外,还需要用到一些代理IP网站
国内资源的话推荐花刺,好代理【网页信息好处理但是TIMEOUT非常多】
国外访问的话可以试一试这个:https://free-proxy-list.net/。网页信息比较好处理而且有许多都是可以用的,基本上跑100条可以出25条非常高了
因为我在国外所以还是先用一下国外的代理网站吧
如果在中国的小伙伴发现网站被墙了就自己换一个网站写代理ip提取吧【滑稽】
首先因为模块化上瘾了,所以基本上没有什么东西是写在main()里面的,但是我还是新建了一个空列表list_ip=[ ]来存放可以使用的ip并且可以自定义导出
0x02 抓取代理IP网站并提取IP和端口
def get_Ip_list():
#获取国外代理IP列表
req=requests.get('https://free-proxy-list.net/',headers=UserAgent2.headers())
soup=BeautifulSoup(req.text,'lxml')
print('抓取IP列表成功')
这里直接暴力获取,然后headers做了随机来反正追踪
这里可以使用re直接暴力提取,然后呢可以用len检测一下ip和端口的长度,如果都是300就说明ip和端口是一一配对的,压缩成一个字典好处理
#上正则强拆
list_ip=re.findall(r'<td>(\d+\.\d+\.\d+\.\d+)</td>',str(soup))#中间这个是ip地址匹配的正则表达式
list_port=re.findall(r'<td>(\d+)</td>',str(soup))#这个匹配单独带有标签的数字
dict_ip=dict(zip(list_ip,list_port))#然后压进字典里面【你想的话可以设置成全局然后到处乱改玩】
print('返回ip字典成功')
return dict_ip
这里soup可以直接使用text来解析,不需要用BS4,为什么我还是用了呢
【本来是想提取高匿的结果发现太tm少了就算了】
但是啊,如果有小伙伴想要提取不止ip和端口的话,可能就要用BS4了,这里稍微讲一下
首先从网站讲起
我贴一段源代码:
<th>IP Address</th><th>Port</th><th>Code</th><th class='hm'>Country</th><th>Anonymity</th><th class='hm'>Google</th><th class='hx'>Https</th><th class='hm'>Last Checked</th></tr></thead><tbody><tr><td>216.177.233.181</td><td>8080</td><td>US</td><td class='hm'>United States</td><td>anonymous</td><td class='hm'>no</td><td class='hx'>no</td><td class='hm'>13 seconds ago</td></tr><tr><td>61.220.26.97</td><td>80</td><td>TW</td><td class='hm'>Taiwan</td><td>anonymous</td><td class='hm'>no</td><td class='hx'>yes</td><td class='hm'>13 seconds ago</td></tr><tr><td>185.119.56.8</td><td>53281</td><td>RU</td><td class='hm'>Russian Federation</td><td>anonymous</td><td class='hm'>no</td><td class='hx'>no</td><td class='hm'>13 seconds ago</td></tr><tr><td>93.183.253.159</td><td>53281</td><td>UA</td><td class='hm'>Ukraine</td><td>elite proxy</td><td class='hm'>no</td><td class='hx'>yes</td><td class='hm'>13 seconds ago</td></tr><tr>
可以发现,每八个td标签为一组ip,所以我们可以写一个循环来提取一下
#解析获得的td标签,每八个为一组
count=0
list_new=[]
list_str=[]
#将当前标签放进缓存列表list_new
for i in soup.find_all('td'):
list_new.append(str(i))
#计数器++
count+=1
#如果当前有八个数据,则说明为一组,合成字符串后放进list_str
if count%8==0:
count=0
#很尬我不想写分组了,直接上re吧......【才不是因为我不会呢】
你们只需要把代码补完就ojbk了反正我是不想写了.....
0x03 跑裤
刚刚我们获得了一个key为IP然后值为端口号的字典,现在就用这个字典做一个随机数的跑裤
#IP跑裤子 说到底都是用随机数跑裤,库足够大就可以追上香港记者
def IP_random():
list_ip=[]
跑的比香港记者还要快啊
然后我们把IP和端口做一个连接,连接成一个string
像这个样子:192.168.1.1:8000
#神奇的操作之遍历key和值
for ip,port in get_Ip_list().items():
list_ip.append(ip+":"+port)
print('返回正确列表')
然后random跑裤返回一个随机的IP+端口
【PS:如果可以的话自己写的时候一定要检查一下IP是不是匹配端口的】
return list_ip[random.randint(0,int(len(list_ip)-1))]
0x04 检查代理是否可以使用
这里推荐一个网站:http://httpbin.org/ip
这个网站源码里面会返回你当前使用的ip,不信你自己试试
所以思路是这样的:
1.使用当前代理ip请求这个网站
2.监听返回,如果成功,到4
3.返回失败,判断原因,timeout可以再次检查,拒绝访问的加入黑名单
4.返回成功,把当前ip加入可用ip列表
设置当前的代理,格式是{'代理类型',‘代理网址’},这里我使用的是http的代理,SOC的还没用用不知道怎么样
def Proxy_get(url='http://httpbin.org/ip'):
proxies={'http':'http://'+IP_random()}
print('当前代理IP设置为:',proxies)
然后尝试以当前ip去获取代理,
try:
print('等待返回')
req=requests.get(str(url),headers=UserAgent2.headers(),proxies=proxies,timeout=5)
soup=req.text
print('反追踪模式-网站源代码获取成功')
#ip=re.findall(r'\d+\.\d+\.\d+\.\d+',str(soup))
list_ip.append(proxies)
print('IP提取成功')
return soup
如果可以了那就直接获得了,但是有的ip是超时的或者拒绝连接的,这时候就要对异常进行处理防止我们的程序挂掉【加不加黑名单是你的事,说不定是你自己网络抽风呢?】
except requests.Timeout:
print('ERROR:超时')
print('重新获取新的代理ip')
except requests.RequestException:
print('由于目标计算机积极拒绝,无法连接。')
print('重新寻找代理IP')
因为我半天找不到那个啥的拒绝连接的错误名叫什么,于是就用了这个返类型错误了,如果有dalao知道怎么找的话还请私信我
演示效果
这个是一个GIF呢为了搞这个我研究了好久怎么导出gif【笑哭】
这个是一个GIF!!
最后
猜猜我这个思路从哪里找的
Bilibili搜索Python代理池有真相
感谢潭州教育的公开课,做的挺良心,就是老师上课常常会翻车
网友评论