00.写在前面:
呃….前两天爬取NSIDC的数据的时候被封IP,导致我不能下载数据,科研止步不前,于是下定决心来建立一个自己的代理IP池。
欢迎大家指出问题,共同学习。我只是一个萌新。。。
所用到的工具: pycharm + python2.7.13 + BeautifulSoup + mysql + MySQLdb
OK,正式开始今天的工作。
01.从免费代理ip网站获取ip:
这里其实就是一般的爬虫过程,与通常所做的工作一样。这里选择了两个网站,分别是西刺代理(http://www.xicidaili.com/)和快代理(https://www.kuaidaili.com/free)其他代理ip网站可以大家再去寻找。
这里以快代理的爬取为例,因为这个网站的爬取过程遇到了一点小问题,让我学习了新的知识。
观察快代理的国内高匿代理的网页,可以看出来页面的改变体现在网页后面的数字上。
https://www.kuaidaili.com/free/inha/1/
https://www.kuaidaili.com/free/inha/2/
https://www.kuaidaili.com/free/inha/3/
......
查看网页源代码也发现,这个网页是个静态网页,我们需要的ip地址和端口信息全都写在网页源码里面。所以只需要爬取标签里面的内容即可。
由于上一次我们采用正则表达式来获取,这一次,就换个套路,利用beautifulsoup来获取,毕竟不用太花时间去想正则的规则。
url = 'https://www.kuaidaili.com/free/inha/{}/'
for num in xrange(1, numpage + 1):
ipurl = url.format(num)
request = urllib2.Request(ipurl, headers=headers)
content = urllib2.urlopen(request).read()
bs = BeautifulSoup(content, 'html.parser')
结果看到使用beautifulsoup解析网页得到的一串乱码。然后就去求助了万能的百度。绝大多数人都给出的解决方案是因为网站编码问题,于是我网页源码里面知道了网页的编码方式,将解析编码方式换成了对应的utf-8
但是仍然是这样的结果。
这里要感谢 知乎某匿名用户的回答(https://www.zhihu.com/question/19696249),人家11年都有这样的水平了,简直可怕!!!经过验证的确解决了问题。但是我也查了很多其他的网站,同样采用的压缩方式,为什么不需要解压缩呢???
ipurl = url.format(num)
request = urllib2.Request(ipurl, headers=headers)
content = urllib2.urlopen(request).read()
data = StringIO.StringIO(content)
gzipper = gzip.GzipFile(fileobj=data)
html = gzipper.read()
bs = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')
res = bs.find_all('tr')
修改代码,加入解压缩的步骤,完美解决问题,得到了网页的源码,从而利用Beautifulsoup得到所需要标签下的内容。
02.获取的IP存入数据库(MySQL):
这里主要涉及到了数据库的一些操作,所使用的库为MySQLdb
。
(1)数据库连接:
def connect_mysql():
conn = MySQLdb.connect(host="localhost",
user="**",
passwd="**",
db="ipproxie",
charset="utf8")
return conn
(2)数据库表的内容增加:
这里我已经在Navicat里面自己创建了一个表(IP),当然也可以利用语句自己创建,这个可以查一查别的资料。
值得注意的是:在execute后,insert 的数据已经进入了mysql,但是如果最后没有commit 的话已经进入数据库的数据会被清除掉,自动回滚
conn = connect_mysql()
cursor = conn.cursor()
sql = "insert into ip values(%s,%s,%s,%s,%s)"
n = cursor.execute(sql, temp)
# 测试表明在execute后,insert 的数据已经进入了mysql,
# 但是如果最后没有commit 的话已经进入数据库的数据会被清除掉,自动回滚
conn.commit()
"insert into ip values(%s,%s,%s,%s,%s)"
表示把1组数据插入到表(IP),这里除了IP地址、端口外,我还保存了IP的类型和一些其他属性。自己根据需要选择存如数据库的内容
这样,我们就完成了代理IP的入库操作,也就是说我们有了一数据库的代理IP。
但是,这些IP是否有用呢,也就是说我们是否能用,还是一个问题。这就设计到了代理IP有效检验问题。
我第一想到的是利用代理IP访问百度一下(www.baidu.com,毕竟其最大功用就是检测能否上网),通过返回值是否为200来判断,但是这种方法耗时太长。
于是在网上找到了另一种方法,这里已经不记得是谁的帮助了,感谢广大网友吧。即利用自带的telnetlib
中的Telnet
来判断。
tn = telnetlib.Telnet(Ip_address, port=Ip_port, timeout=20)
如果通过则存入数据库,否则跳过。这样,我们就完成了自己IP数据库的建立。
PS. 写在后面:
其实我们这样建立的IP数据库经过一段时间,里面存储的IP地址也会失效,所以我们需要经常性的来检验数据库中存储的IP地址是否可用。
这里就要提到windows自带的计划任务功能了。
利用windows的计划任务,指定程序在指定时间运行,从而更新我们的数据库,保证数据库内的IP地址的可用性是很重要的。
(1)在控制面板
里面找到管理工具——计划任务
(2)点击创建基本任务
(3)根据提示填写每一步的内容。包括任务名、触发时间、触发内容等。
接下来就是安安静静的等待晚上他自己执行并更新我们的数据库了。哈哈哈哈哈哈哈哈哈哈哈哈哈。
源码位置(偷偷让大家进去下我的GitHub,哈哈哈哈):https://github.com/moonlighf/Leetcode/tree/master/01.IpProxie
欢迎大家指出问题,共同学习。我只是一个萌新。。。