对于爬虫来说,由于爬虫爬取速度过快,在爬取过程中可能遇到同一个 IP 访问过于频繁的问题,此时网站就会让我们输入验证码登录或者直接封锁 IP,这样会给爬取带来极大的不便。
使用代理隐藏真实的 IP,让服务器误以为是代理服务器在请求自己。这样在爬取过程中通过不断更换代理,就不会被封锁,可以达到很好的爬取效果。
代理分类时,既可以根据协议区分,也可以根据其匿名程度区分,总结如下:
根据协议区分
根据匿名程度区分
常见代理类型
对于 requests 来说,代理设置非常简单,只需传入 proxies 参数即可
代码如下:
import requests
proxy = '221.180.170.104:8080'
proxies = {
'http': 'http://' + proxy,
'https': 'https://' + proxy,
}
try:
response = requests.get('http://httpbin.org/ip', proxies=proxies)
print(response.text)
except Exception as e:
print('Error', e.args)
运行结果如下:
{
"origin": "221.180.170.104"
}
对于 aiohttp 来说,可以通过 proxy 参数直接设置即可,HTTP 代理设置如下:
import asyncio
import aiohttp
proxy = 'http://140.143.6.16:1080'
async def main():
async with aiohttp.ClientSession() as session:
try:
async with session.get('http://httpbin.org/ip', proxy=proxy) as response:
print(await response.text())
except Exception as e:
print('Error:', e.args)
if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(main())
运行结果如下:
{
"origin": "140.143.6.16"
}
运行结果的 origin 如果是代理服务器的 IP,则证明代理已经设置成功。
将网站的代理爬取下来后,就需要批量快速的验证代理IP是否可用。
代理的数量很多的时候,为了提高代理的检测效率,使用异步请求库 aiohttp 来进行检测。
requests 作为一个同步请求库,我们在发出一个请求之后,程序需要等待网页加载完成之后才能继续执行。也就是这个过程会阻塞等待响应,如果服务器响应非常慢,比如一个请求等待十几秒,那么我们使用 requests 完成一个请求就会需要十几秒的时间,程序也不会继续往下执行,而在这十几秒的时间里程序其实完全可以去做其他的事情,比如调度其他的请求或者进行网页解析等。
对于响应速度比较快的网站来说,requests 同步请求和 aiohttp 异步请求的效果差距没那么大。可对于检测代理的网站来说,检测一个代理获得响应需要等待的时间较长,这时候使用 aiohttp 异步请求库的优势就体现出来了,检测效率会大大提高。
读取数据:
with open('代理IP数据.txt', 'r', encoding='utf-8') as f:
con = f.readlines()
print(f'共有代理IP数据:{len(con)}条')
运行结果如下:
共有代理IP数据:1690条
Process finished with exit code 0
批量验证代理IP是否可用:
import asyncio
import aiohttp
import re
with open('代理IP数据.txt', 'r', encoding='utf-8') as f:
con = f.readlines()
print(f'共有代理IP数据:{len(con)}条')
proxy_ips = []
for x in con:
m = x.split('@')
proxy_ips.append(m[0])
print(proxy_ips)
n = len(proxy_ips)
useful_ip = []
async def test(i):
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session:
try:
async with session.get('http://httpbin.org/ip', proxy=f'http://{proxy_ips[i]}') as response:
result = await response.text()
print(result)
datas = re.findall('"(.*?)": "(.*?)"', result)
_, proxy = datas[0]
if proxy in proxy_ips[i]:
useful_ip.append(proxy_ips[i])
print(f'该代理ip有效:{proxy_ips[i]}')
except Exception as e:
print('Error', e)
scrape_index_tasks = [asyncio.ensure_future(test(x)) for x in range(n)]
loop = asyncio.get_event_loop()
tasks = asyncio.gather(*scrape_index_tasks)
loop.run_until_complete(tasks)
print(useful_ip)
with open('可用代理IP.txt', 'w') as f:
for item in useful_ip:
f.write(item + '\n')
运行效果如下:
使用异步请求库 aiohttp 来进行检测代理IP是否可用,相比于requests 同步请求来说,效率非常快,程序运行成功,初步筛选出了部分可用代理IP,并保存到了txt里。
作者:叶庭云 公众号:微信搜一搜【修炼Python】 分享Python爬虫、数据分析、数据可视化、机器学习有关知识和实例;也分享实用的资料教程、软件工具、学习文档和简历模板。发现求知的乐趣,在不断总结和学习中进步。坚持输出优质文章,期待你的关注,一起交流学习,互相成就。 发现求知的乐趣,在不断总结和学习中进步,与诸君共勉。