刚刚学习了爬虫入门爬取小说,觉得那是不够的,很多时候你仅仅伪装成浏览器是解决不了问题的,还需要解决别人封你的ip的问题,所以我又学习了如何爬虫是更换自己的ip,想要有足够的ip来供你更换,一定得先搭建你的ip代理池,那么我们就先搭建自己的ip代理池。
什么是ip代理池,就是很多代理ip地址放到一起足够让你去更换,那么我们从哪里去获取足够多的ip呢,当然很多前人已经帮我们解决问题了我目前只是入门了,所以我用的是https://www.xicidaili.com/nn/1这个网站,我们先想爬小说一样爬取这个网站上的代理ip,由于我还不会使用数据库我们就先把这个代理ip以字典的形式存放在文本文件里面,看起来很容易,不过本蒟蒻弄了好久,遇到了很多问题:
- 爬取西刺网上的ip时每一个页的每个ip有很多信息包括,ip地址,端口,地址,速度等信息,如果你想爬取小说那样用正则表达式是有问题的,信息太多啦,一个要用''' '''才能包含下,而且一个不小心就会,啥页提取不出来,后面才知道用的xpath提取的,需要bs4,lxml库,不过在声明的时候它又说我这个没有这个包,需要安装,要需要导入,这些操作都是网上有的我就不细说了。反正搞啦好久才解决问题。
- 学习的时候很多人都告诉你,很多ip是不能用的,需要自己手动检测,然后就需要写一个检测ip是否有效果的问题了。
- 爬取ip地址的时候还遇到了,html是乱码的问题,要他用ecodeing='gbk',虽然西刺网没有这个情况.
参考:怎样简单的搭建一个免费的IP代理池,python中requests爬去网页内容出现乱码的解决方案
代码:
import requests
from lxml import etree
import re
import time
import random
import telnetlib
def check(ip,port):
try:
telnetlib.Telnet(ip, port, timeout=20)
except:
return False
else:
return True
send_headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36",
"Connection": "keep-alive",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8"
} # 伪装成浏览器
def get_agent():
agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv,2.0.1) Gecko/20100101 Firefox/4.0.1',
'Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)'
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0'
]#获取agent 在多个模拟的浏览器中随机选取一个
fakeheader = {}
fakeheader['User-agent'] = agents[random.randint(0, len(agents)-1)]
return fakeheader
def get_iplist(url,max_page):
ip_list={}
for i in range(1,max_page+1):#爬取很多页的代理ip
response=requests.get(url+str(i),headers=get_agent())
response.encoding='utf-8'
html=response.text
response.close()
info = etree.HTML(html)
address = info.xpath('//tr[@class="odd" or class=""]/td[2]/text()') # IP地址
ports = info.xpath('//tr[@class="odd" or class=""]/td[3]/text()') # 端口
anonymous = info.xpath('//tr[@class="odd" or class=""]/td[5]/text()') # 匿名形式
http_https = info.xpath('//tr[@class="odd" or class=""]/td[6]/text()') # http or https
speed = info.xpath('//tr[@class="odd" or class=""]/td[7]/div[1]/@title') # 连接速度
speed_width = info.xpath('//tr[@class="odd" or class=""]/td[7]/div[1]/div/@style') # 连接速度的比例
conn_time = info.xpath('//tr[@class="odd" or class=""]/td[8]/div[1]/@title') # 连接时间
conn_time_width = info.xpath('//tr[@class="odd" or class=""]/td[8]/div[1]/div/@style') # 连接时间的比例
life = info.xpath('//tr[@class="odd" or class=""]/td[9]/text()') # 存活时间
test = info.xpath('//tr[@class="odd" or class=""]/td[10]/text()') # 检验时间
cnt=int(0)
for i in range(0,len(address)-1):
if check(address[i],ports[i]):
ip_list[str(cnt+1)]={
'IP地址': address[i]+':'+ports[i],
'是否匿名': anonymous[i],
'类型': http_https[i],
'速度': eval((re.compile('(.*?)秒').findall(speed[i]))[0]),
'速度比例': eval((re.compile('width:(.*?)%').findall(speed_width[i]))[0]),
'连接时间': eval((re.compile('(.*?)秒').findall(conn_time[i]))[0]),
'耗时比例': eval((re.compile('width:(.*?)%').findall(conn_time_width[i]))[0]),
'存活时间': eval((re.compile('(\d+).*?').findall(life[i]))[0]),
'验证时间': test[i]
}
try :
#with open('porxy_ip.csv', 'w', encoding='utf-8') as fp:
fp.write(str(ip_list[str(cnt+1)]))
fp.write('\n')
print('成功写入ip及端口:%s'%(address[i]+':'+ports[i]))
cnt=cnt+1
except:
print("写入错误!")
#exit()
else :
pass
return ip_list
ip_url='https://www.xicidaili.com/nn/'
fp=open('porxy_ip.csv', 'w', encoding='utf-8')
max_page=1
ip=get_iplist(ip_url,max_page)
print('成功写入%s个可用ip地址'%str(len(ip)))