为什么会出现IP被封
网站为了防止被爬取,会有反爬机制,对于同一个IP地址的大量同类型的访问,会封锁IP,过一段时间后,才能继续访问
如何应对IP被封的问题
有几种套路:
- 修改请求头,模拟浏览器(而不是代码去直接访问)去访问
- 采用代理IP并轮换
- 设置访问时间间隔
如何获取代理IP地址
- 从该网站获取: https://www.xicidaili.com/
- inspect -> 鼠标定位:
- 要获取的代理IP地址,属于class = "odd"标签的内容:代码如下,获取的代理IP保存在proxy_ip_list列表中
# show your code
# 案例代码
from bs4 import BeautifulSoup
import requests
import timedef open_proxy_url(url):user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'headers = {'User-Agent': user_agent}try:r = requests.get(url, headers = headers, timeout = 20)r.raise_for_status()r.encoding = r.apparent_encodingreturn(r.text)except:print('无法访问网页' + url)def get_proxy_ip(response):proxy_ip_list = []soup = BeautifulSoup(response, 'html.parser')proxy_ips = soup.select('.odd')#选择标签for proxy_ip in proxy_ips:ip = proxy_ip.select('td')[1].textport = proxy_ip.select('td')[2].textprotocol = proxy_ip.select('td')[5].textif protocol in ('HTTP','HTTPS'):proxy_ip_list.append(f'{protocol}://{ip}:{port}')return proxy_ip_listif __name__ == '__main__':proxy_url = 'https://www.xicidaili.com/'text = open_proxy_url(proxy_url)proxy_ip_filename = 'proxy_ip.txt'with open(proxy_ip_filename, 'w') as f:f.write(text)text = open(proxy_ip_filename, 'r').read()proxy_ip_list = get_proxy_ip(text)print(proxy_ip_list)
# text
获取如下数据:
获取到代理IP地址后,发现数据缺失很多,再仔细查看elements,发现有些并非class = “odd”,而是…,这些数据没有被获取
class = "odd"奇数的结果,而没有class = "odd"的是偶数的结果
通过bs4的find_all(‘tr’)来获取所有IP:
# show your code
def get_proxy_ip(response):proxy_ip_list = []soup = BeautifulSoup(response, 'html.parser')proxy_ips = soup.find(id = 'ip_list').find_all('tr')for proxy_ip in proxy_ips:if len(proxy_ip.select('td')) >=8:ip = proxy_ip.select('td')[1].textport = proxy_ip.select('td')[2].textprotocol = proxy_ip.select('td')[5].textif protocol in ('HTTP','HTTPS','http','https'):proxy_ip_list.append(f'{protocol}://{ip}:{port}')return proxy_ip_list
使用代理
- proxies的格式是一个字典:
- {‘http’: ‘http://IP:port‘,‘https’:'https://IP:port‘}
- 把它直接传入requests的get方法中即可
- web_data = requests.get(url, headers=headers, proxies=proxies)
# show your code
def open_url_using_proxy(url, proxy):user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'headers = {'User-Agent': user_agent}proxies = {}if proxy.startswith('HTTPS'):proxies['https'] = proxyelse:proxies['http'] = proxytry:r = requests.get(url, headers = headers, proxies = proxies, timeout = 10)r.raise_for_status()r.encoding = r.apparent_encodingreturn (r.text, r.status_code)except:print('无法访问网页' + url)return False
url = 'http://www.baidu.com'
text = open_url_using_proxy(url, proxy_ip_list[0])
无法访问网页http://www.baidu.com
确认代理IP地址有效性
- 无论是免费还是收费的代理网站,提供的代理IP都未必有效,我们应该验证一下,有效后,再放入我们的代理IP池中,以下通过几种方式:访问网站,得到的返回码是200真正的访问某些网站,获取title等,验证title与预计的相同访问某些可以提供被访问IP的网站,类似于“查询我的IP”的网站,查看返回的IP地址是什么验证返回码
# show your code
def check_proxy_avaliability(proxy):url = 'http://www.baidu.com'result = open_url_using_proxy(url, proxy)VALID_PROXY = Falseif result:text, status_code = resultif status_code == 200:print('有效代理IP: ' + proxy)else:print('无效代理IP: ' + proxy)
改进:确认网站title
# show you code
def check_proxy_avaliability(proxy):url = 'http://www.baidu.com'text, status_code = open_url_using_proxy(url, proxy)VALID = Falseif status_code == 200:if r_title:if r_title[0] == '<title>百度一下,你就知道</title>':VALID = Trueif VALID:print('有效代理IP: ' + proxy)else:print('无效代理IP: ' + proxy)
完整代码
from bs4 import BeautifulSoup
import requests
import re
import jsondef open_proxy_url(url):user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'headers = {'User-Agent': user_agent}try:r = requests.get(url, headers = headers, timeout = 10)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept:print('无法访问网页' + url)def get_proxy_ip(response):proxy_ip_list = []soup = BeautifulSoup(response, 'html.parser')proxy_ips = soup.find(id = 'ip_list').find_all('tr')for proxy_ip in proxy_ips:if len(proxy_ip.select('td')) >=8:ip = proxy_ip.select('td')[1].textport = proxy_ip.select('td')[2].textprotocol = proxy_ip.select('td')[5].textif protocol in ('HTTP','HTTPS','http','https'):proxy_ip_list.append(f'{protocol}://{ip}:{port}')return proxy_ip_listdef open_url_using_proxy(url, proxy):user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'headers = {'User-Agent': user_agent}proxies = {}if proxy.startswith(('HTTPS','https')):proxies['https'] = proxyelse:proxies['http'] = proxytry:r = requests.get(url, headers = headers, proxies = proxies, timeout = 10)r.raise_for_status()r.encoding = r.apparent_encodingreturn (r.text, r.status_code)except:print('无法访问网页' + url)print('无效代理IP: ' + proxy)return Falsedef check_proxy_avaliability(proxy):url = 'http://www.baidu.com'result = open_url_using_proxy(url, proxy)VALID_PROXY = Falseif result:text, status_code = resultif status_code == 200:r_title = re.findall('<title>.*</title>', text)if r_title:if r_title[0] == '<title>百度一下,你就知道</title>':VALID_PROXY = Trueif VALID_PROXY:check_ip_url = 'https://jsonip.com/'try:text, status_code = open_url_using_proxy(check_ip_url, proxy)except:returnprint('有效代理IP: ' + proxy)with open('valid_proxy_ip.txt','a') as f:f.writelines(proxy)try:source_ip = json.loads(text).get('ip')print(f'源IP地址为:{source_ip}')print('='*40)except:print('返回的非json,无法解析')print(text)else:print('无效代理IP: ' + proxy)if __name__ == '__main__':proxy_url = 'https://www.xicidaili.com/'proxy_ip_filename = 'proxy_ip.txt'text = open(proxy_ip_filename, 'r').read()proxy_ip_list = get_proxy_ip(text)for proxy in proxy_ip_list:check_proxy_avaliability(proxy)
无法访问网页http://www.baidu.com
无效代理IP: HTTP://113.194.28.11:9999
无效代理IP: HTTP://113.194.28.11:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://113.195.168.115:48888
无效代理IP: HTTP://113.195.168.115:48888
无法访问网页http://www.baidu.com
无效代理IP: HTTP://118.113.247.115:9999
无效代理IP: HTTP://118.113.247.115:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://60.167.112.236:1133
无效代理IP: HTTP://60.167.112.236:1133
无法访问网页http://www.baidu.com
无效代理IP: HTTP://101.132.190.101:80
无效代理IP: HTTP://101.132.190.101:80
无法访问网页http://www.baidu.com
无效代理IP: HTTP://111.222.141.127:8118
无效代理IP: HTTP://111.222.141.127:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://117.88.177.101:3000
无效代理IP: HTTPS://117.88.177.101:3000
无法访问网页http://www.baidu.com
无效代理IP: HTTP://183.166.136.144:8888
无效代理IP: HTTP://183.166.136.144:8888
无法访问网页http://www.baidu.com
无效代理IP: HTTP://27.208.231.100:8060
无效代理IP: HTTP://27.208.231.100:8060
无法访问网页http://www.baidu.com
无效代理IP: HTTP://123.169.99.177:9999
无效代理IP: HTTP://123.169.99.177:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://119.84.84.185:12345
无效代理IP: HTTP://119.84.84.185:12345
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://114.99.54.65:8118
无效代理IP: HTTPS://114.99.54.65:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://119.4.13.26:1133
无效代理IP: HTTPS://119.4.13.26:1133
无法访问网页http://www.baidu.com
无效代理IP: HTTP://58.253.158.177:9999
无效代理IP: HTTP://58.253.158.177:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://114.223.208.165:8118
无效代理IP: HTTP://114.223.208.165:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTP://112.84.73.53:9999
无效代理IP: HTTP://112.84.73.53:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://221.237.37.137:8118
无效代理IP: HTTP://221.237.37.137:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://117.45.139.84:9006
无效代理IP: HTTPS://117.45.139.84:9006
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://171.35.86.72:8118
无效代理IP: HTTPS://171.35.86.72:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTP://49.235.246.24:8118
无效代理IP: HTTP://49.235.246.24:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTP://112.95.205.138:8888
无效代理IP: HTTP://112.95.205.138:8888
无法访问网页http://www.baidu.com
无效代理IP: HTTP://14.115.105.104:808
无效代理IP: HTTP://14.115.105.104:808
无法访问网页http://www.baidu.com
无效代理IP: HTTP://60.191.11.249:3128
无效代理IP: HTTP://60.191.11.249:3128
无法访问网页http://www.baidu.com
无效代理IP: HTTP://14.115.104.119:808
无效代理IP: HTTP://14.115.104.119:808
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://121.13.252.60:41564
无效代理IP: HTTPS://121.13.252.60:41564
无法访问网页http://www.baidu.com
无效代理IP: HTTP://112.95.205.135:9000
无效代理IP: HTTP://112.95.205.135:9000
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://125.123.139.19:9000
无效代理IP: HTTPS://125.123.139.19:9000
无法访问网页https://jsonip.com/
无效代理IP: HTTP://218.27.204.240:8000
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://116.204.142.62:8080
无效代理IP: HTTPS://116.204.142.62:8080
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://60.191.11.229:3128
无效代理IP: HTTPS://60.191.11.229:3128
无法访问网页http://www.baidu.com
无效代理IP: HTTP://163.125.71.198:9999
无效代理IP: HTTP://163.125.71.198:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://14.115.107.232:808
无效代理IP: HTTP://14.115.107.232:808
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://113.78.255.93:9000
无效代理IP: HTTPS://113.78.255.93:9000
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://60.191.11.237:3128
无效代理IP: HTTPS://60.191.11.237:3128
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://58.255.38.156:9000
无效代理IP: HTTPS://58.255.38.156:9000
无法访问网页http://www.baidu.com
无效代理IP: HTTP://163.125.71.195:8888
无效代理IP: HTTP://163.125.71.195:8888
无法访问网页http://www.baidu.com
无效代理IP: HTTP://123.163.24.113:3128
无效代理IP: HTTP://123.163.24.113:3128
无法访问网页http://www.baidu.com
无效代理IP: HTTP://222.240.184.126:8086
无效代理IP: HTTP://222.240.184.126:8086
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://117.141.155.241:53281
无效代理IP: HTTPS://117.141.155.241:53281
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://218.22.7.62:53281
无效代理IP: HTTPS://218.22.7.62:53281
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://121.13.252.60:41564
无效代理IP: HTTPS://121.13.252.60:41564
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://125.123.139.19:9000
无效代理IP: HTTPS://125.123.139.19:9000
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://117.88.177.101:3000
无效代理IP: HTTPS://117.88.177.101:3000
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://116.204.142.62:8080
无效代理IP: HTTPS://116.204.142.62:8080
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://114.99.54.65:8118
无效代理IP: HTTPS://114.99.54.65:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://60.191.11.229:3128
无效代理IP: HTTPS://60.191.11.229:3128
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://119.4.13.26:1133
无效代理IP: HTTPS://119.4.13.26:1133
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://113.78.255.93:9000
无效代理IP: HTTPS://113.78.255.93:9000
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://117.45.139.84:9006
无效代理IP: HTTPS://117.45.139.84:9006
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://60.191.11.237:3128
无效代理IP: HTTPS://60.191.11.237:3128
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://171.35.86.72:8118
无效代理IP: HTTPS://171.35.86.72:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://58.255.38.156:9000
无效代理IP: HTTPS://58.255.38.156:9000
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://114.223.103.47:8118
无效代理IP: HTTPS://114.223.103.47:8118
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://117.141.155.241:53281
无效代理IP: HTTPS://117.141.155.241:53281
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://218.22.7.62:53281
无效代理IP: HTTPS://218.22.7.62:53281
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://14.153.52.10:3128
无效代理IP: HTTPS://14.153.52.10:3128
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://61.164.39.69:53281
无效代理IP: HTTPS://61.164.39.69:53281
有效代理IP: HTTPS://113.65.163.199:9797
源IP地址为:14.145.235.76
========================================
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://58.251.235.76:9797
无效代理IP: HTTPS://58.251.235.76:9797
无法访问网页http://www.baidu.com
无效代理IP: HTTPS://183.166.103.164:9999
无效代理IP: HTTPS://183.166.103.164:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://112.95.205.138:8888
无效代理IP: HTTP://112.95.205.138:8888
无法访问网页http://www.baidu.com
无效代理IP: HTTP://14.115.105.104:808
无效代理IP: HTTP://14.115.105.104:808
无法访问网页http://www.baidu.com
无效代理IP: HTTP://113.194.28.11:9999
无效代理IP: HTTP://113.194.28.11:9999
无法访问网页http://www.baidu.com
无效代理IP: HTTP://60.191.11.249:3128
无效代理IP: HTTP://60.191.11.249:3128
关于http和https代理
- 可以看到proxies中有两个键值对:
- {‘http’: ‘http://IP:port‘,‘https’:'https://IP:port‘}
- 其中 HTTP 代理,只代理 HTTP 网站,对于 HTTPS 的网站不起作用,也就是说,用的是本机 IP,反之亦然。
- 我刚才使用的验证的网站是https://jsonip.com, 是HTTPS网站所以探测到的有效代理中,如果是https代理,则返回的是代理地址
- 如果是http代理,将使用本机IP进行访问,返回的是我的公网IP地址