ip池的搭建 以及使用自定义模块
由于使用本地ip频繁爬取某个网站,可能会被封ip,因此搭建自己的ip池十分重要。对于反反爬而言,这是一个好方法。
准备工作
这次爬取的网站是快代理中的免费代理。
网站连接如下:
https://www.kuaidaili.com/free/
首先加载一些爬虫必要的库
import requests
from bs4 import BeautifulSoup
import re
import time
没有安装的同学自行安装下
爬虫ip逻辑
1. 获取目标网页的url
2. 解析该网页内容
3. 得到目标ip
4. 检测ip是否可用
5. 存储有效ip
首先定义创建三个list,用于存储之后爬取的ip,端口,类型
然后定义一个获取目标网页的方法。
ip = []
port = []
type = []
def get_url(page):#传入的数据是爬取目标网页的页数
for i in range(int(page)):
try:
print('正在爬取第%d页'%(i+1))
url = 'https://www.kuaidaili.com/free/inha/{}/'.format(i+1)
print("爬取网址为:",url)
IP1,PORT1,TYPE1=get_content(url)#这是一个自定义解析网页内容的方法
process_data(IP1,PORT1,TYPE1)
print('休息一下')
time.sleep(3)#防止访问频率过快,被封
except Exception as e:
print('爬取失败',e)
然后在获取了目标url后,就是解析网页的内容。
def get_content(url):
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'}#加载伪装头防止反爬
response = requests.get(url,headers=headers)
if response.status_code == 200:
print('连接正常')
soup = BeautifulSoup(response.text,'lxml')#利用Beautifulsoup解析爬取的内容
contents = soup.find_all('td')
IP = []
PORT = []
TYPE = []#用于存储爬取的目标内容
for content in contents:
content = str(content)
#利用正则表达式匹配目标内容
if re.findall(r'[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*',content):
IP.append(re.findall(r'[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*',content))
elif re.findall(r'<td data-title="PORT">',content):
PORT.append(re.findall(r'\d{4}',content))
elif re.findall(r'<td data-title="类型">',content):
TYPE.append(re.findall('[A-Z]{4,5}',content))
return IP,PORT,TYPE
else:
print('连接失败或遭遇反爬')
接下来就是处理数据,因为这个程序中IP、PORT、TYPE存储的是每一页的数据,因此需要把这些数据汇总。因此定义一个处理数据的方法。
def process_data(IP,PORT,TYPE):
for content in IP:
ip.append(content[0])
for content in PORT:
port.append(content[0])
for content in TYPE:
type.append(content[0])
reg = []
for i in range(len(ip)):
dic ={
}
dic[type[i]] = ip[i]+':'+port[i]
reg.append(dic)
can_use = check_ip(reg)#定义检测ip有效的方法
print('有用的ip数量为:',len(can_use))
save_ip(can_use)#定义一个保存有效ip的方法
接下来就是检测IP有效性
我们利用某度进行检测,将ip传入proxies中去验证,如果返回的state_code = 200,在规定的时间内,就说明这个ip是有效的。否则就报错,这里用try、except 结构避免报错后无法继续跑程序的问题。
def