大家好,今天给大家分享一个爬取免费代理IP的一段代码。
首先说一下思路。
1,预先从代理IP网站,爬取代理IP信息,存到数据库。
2,从数据库中随机提取一条代理IP。
3,提取代理IP需要注意有校性,通过和百度网站测试,删除无效代理IP,返回有效的代理IP。
说一下依赖包,然后我用的是Python3.6+Ubuntu16.04
import requests
from scrapy.selector import Selector
import pymysql
首先就是requests模块,用来发送请求。
然后就是 scrapy, 没错这就是爬虫框架,但是我们现在就只用到里面的Selector选择器进行提取数据,用起来比lxml方便多了。
最后就是数据库,这边我用的是最熟悉的MySQL数据,当然最优的选择是redis数据库,但是好多人对NoSQL数据不是很熟悉,所以我使用MySQL数据库来保存数据。
好现在开始代码实现,实现之前我们先创建数据库和数据表
"""
create databases proxy_ip charset=utf8;
CREATE TABLE `ip_info` (
`ip` varchar(20) NOT NULL,
`port` varchar(5) NOT NULL,
`speed` float DEFAULT NULL,
`proxy_type` varchar(5) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
"""
1
爬取数据存入数据库
# 链接mysql数据库
conn = pymysql.connect(host='localhost', port=3306, database='proxy_ip', user='root',
password='mysql', charset='utf8')
# 获取游标对象
cus = conn.cursor()
# 首先定义一个函数来抓取代理IP到数据库当中
def crawl_ips():
# 首先清空表
sql = "delete from ip_info;"
# 执行
cus.execute(sql)
# 提交
conn.commit()
url = "http://www.xicidaili.com/nn/{}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6"}
# 记录次数
num = 0
# 我们循环10页抓取
for p in range(1, 11):
re = requests.get(url.format(p), headers=headers)
# 我用了scrapy 框架里面的选择器
select = Selector(text=re.text)
all_trs = select.xpath('//table[@id="ip_list"]')[0]
# 获取整个tr标签
tr_list = all_trs.xpath("//tr")[1:] # 去掉标题
for tr in tr_list:
# 提取ip
ip = tr.xpath('./td[2]/text()').extract()[0]
# 提取端口
port = tr.xpath('./td[3]/text()').extract()[0]
# proxy_info['address'] = tr.xpath('./td[4]/a/text()').extract()[0]
# 提取速度
speed = tr.xpath('./td[7]/div/@title').extract()[0]
speed = (speed.split("秒"))[0] # 从中把数字数据提取出来
# 提取类型(http或者https)
type = tr.xpath('./td[6]/text()').extract()[0]
# 把延迟速度小于2秒的存入数据可
if float(speed)
print("爬取的ip", ip, port, type, speed)
sql = """insert into ip_info (ip, port, speed, proxy_type) values ('', '', , '')""".format(
ip, port, speed, type
)
# 执行
cus.execute(sql)
# 提交
conn.commit()
num += 1
print("已经抓取{}条代理ip".format(num))
调用这个函数crawl_ips() 往mysql数据库中存入数据
2
从数据库中取出有效代理IP并格式化好
我们先定义一个类,方便后面导入获取可用的代理IP
class GetIp(object):
# 首先我们先定义一个方法判断代理IP是否可用,具体方法就是通过测试百度的服务器判断 状态码 是否在200到300之间
def judge_ip(self, ip, port, proxy_type):
"""
判断是否有效
:param ip:
:param port:
:param proxy_type:
:return: bool
"""
http_url = "http://www.baidu.com"
proxy_ip = "://:".format(proxy_type, ip, port)
try:
proxy_dict = {
proxy_type: proxy_ip
}
response = requests.get(http_url, proxies=proxy_dict)
except Exception as e:
print("invalid ip and port", ip, port, proxy_type, e)
self.del_ip(ip)
return False
else:
code = response.status_code
if 200
# print("有效", ip, port, proxy_type)
return True
else:
self.del_ip(ip)
return False
# 删除无效的代理IP
def del_ip(self, ip):
"""删除无效ip"""
sql = """delete from ip_info WHERE ip='{}'""".format(ip)
# 执行
cus.execute(sql)
# 提交
conn.commit()
# 随机获取一个代理IP,获取时先判断是否能用,不能则删除,继续随机获取,直到获取成功
def get_random_ip(self):
"""
获取随机ip
:return: (ip, port, proxy_type)
"""
sql = """select ip,port,proxy_type from ip_info order by RAND() limit 1;"""
cus.execute(sql)
for ip_info in cus.fetchall():
ip = ip_info[0]
port = ip_info[1]
proxy_type = ip_info[2]
if self.judge_ip(ip, port, proxy_type):
# print("有效的ip")
# return ip, port, proxy_type
return "://:".format(proxy_type, ip, port)
else:
# print("再次尝试!")
# time.sleep(1)
self.get_random_ip()
# 最后我们可以测试一下
# 一, 先用crawl_ips()方法抓取代理IP,前提是首先见好了数据库,连接好了表
if __name__ == '__main__':
# crawl_ips() # 先单独调用此函数 爬取代理ip 然后注释掉 测试提取出代理ip
# 二, 在把 crawl_ips()注释,实例化一个对象来获取一个可用的随机代理IP
test_net = GetIp()
ip = test_net.get_random_ip()
print(ip)
效果图:如下
调用函数 效果图
总结,这段脚本了,有两个看点吧,一是如何爬取代理IP,我使用了Scrapy框架里面的选择器来进行提取数据,二就是如何判断一个能用的代理IP,用百度这个网址去测试是否可用。
嗯....这个代理IP个人勉强用,企业里面基本都是花钱买代理IP,毕竟免费的,都不好用,最后代理IP的速度是远不如自己本机的IP的,尽量保证自己的本地IP不要被Ban掉,能把阈值测试出来就更好了!加油各位大佬们。
IT技术大神∣小白到大神的进阶之路
领取专属 10元无门槛券
私享最新 技术干货