网络爬虫最常遇到的反爬措施是限制用户IP的一段时间内的访问次数,也就是说同一IP地址在短时间内频繁多次地访问目标网站,网站可能会针对此IP地址进行限制或封禁。在采集数据时对于这种情况,通常会使用代理来伪装本地IP进行访问,若需要大量获取某一目标数据,就需要建立具有一定数量代理IP的代理池,从而批量任意选取IP进行伪装访问。
### 1.用代理进行访问
为了能够使用代理进行访问,我们首先需要获得一个有效代理,代理一般有免费和付费两种。免费的代理由于使用次数多,来源不可靠等因素,多数情况下并不稳定,付费的代理相对来说就稳定和可靠很多,使用质量也有所保证,因此通常情况下大家都是使用付费代理。代理的使用通常也可分为两种,全局代理和局部代理。所谓全局代理,也就是使物理设备整体的网络访问都经过代理,这样网络采集代码不需要做任何修改,就可以实现伪装访问。但通常情况下,一个代理IP的有效性时间有限,而且若是目标网站限制严重,就需要频繁切换代理,这样一来全局代理在网络爬虫时就不适用了。对此我们可以利用代码实现局部或单次的代理访问,从而满足大量访问的需求。
假设我们获取了一条有效的代理:111.222.33.144:80,我们尝试使用这条代理进行访问
```python
import requests
url = 'http://httpbin.org/get'
proxy = '111.222.33.144:80'
proxies = {
'http': 'http://' + proxy,
'https':'https://' + proxy,
}
try:
response = requests.get(url,proxies=proxies)
print(response.text)
except Exception as e:
print(e)
```
运行结果:
```python
{
"args": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Host": "httpbin.org",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "python-requests/2.22.0",
},
"origin": "111.222.33.144, 111.222.33.144",
"url": "https://httpbin.org/get"
}
```
如果获取到的结果与我们使用的代理一致,则说明我们成功使用此代理进行了一次请求。
若使用SOCKS5,我们需要安装具有socks功能的requests,
```bash
pip3 install requests[socks]
```
之后只需将代理字典中的'http://'和'https://'改成'socks5://'即可,其他步骤不变。
```python
proxies = {
'http': 'socks5://' + proxy,
'https':'socks5://' + proxy,
}
```
### 2.建立代理池
学会了使用代理,接下来让我们建立一个代理池,以实现批量的伪装访问。
- 首先,我们需要批量获取代理IP,假设我们通过付费代理,批量获取了一批代理IP,并保存到Redis数据库中。
```python
import redis
# 获取到的代理IP
proxies = [
'180.247.183.48:9999',
'106.56.247.152:8888',
'115.151.131.99:7777',
'106.56.244.233:6666',
'112.72.109.148:5555',
'106.56.246.75:4444',
'115.72.99.122:3333',
'180.107.214.26:2222',
'106.52.246.43:1111',
'115.148.23.245:8000',
]
# 连接Redsi数据库
db = redis.StrictRedis(host='localhost',port=6379,db=0)
# 设置Key名
REDIS_KEY = 'my_proxies'
# 将获取到的IP保存进Redsi数据库
for proxy in proxies:
db.sadd(REDIS_KEY,proxy)
print("Proxies: ", db.scard(REDIS_KEY))
```
接着我们需要验证获取的代理IP是否都可用,将可用的保留,不可用的剔除,通常来说每隔一段时间就需要检测一次。```python
import requests
import redis
# 连接Redis数据库
db = redis.StrictRedis(host='localhost',port=6379,db=0)
REDIS_KEY = 'my_proxies'
proxies = db.smembers(REDIS_KEY)
# 测试IP的网站
test_url = 'http://www.baidu.com'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3729.157 Safari/537.36'}
# 遍历所有获取的IP,访问测试网址
for ip in proxies:
proxy = {
'http': 'http://' + proxy,
'https':'https://' + proxy,
}
try:
response = requests.get(test_url,headers=headers,proxies=proxy)
if not response.status_code == 200:
db.srem(REDIS_KEY,ip)
except Exception as e:
print(e)
```
最后,我们就可以随机放心地使用代理访问目标网站了
```python
import requests
import redis
db = redis.StrictRedis(host='localhost',port=6379,db=0)
REDIS_KEY = 'my_proxies'
target_url = 'http://www.baidu.com'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3729.157 Safari/537.36'}
proxy = db.spop(REDIS_KEY)
proxies = {
'http': 'http://' + proxy,
'https':'https://' + proxy,
}
# 使用代理访问目标网站
try:
response = requests.get(target_url,headers=headers,proxies=proxies)
print(response.text)
except Exception as e:
print(e)
```
支持全球240个国家地区,每日超9000万住宅动态IP资源,欢迎访问:www.ipidea.net。