13.3 获取免费代理
现在,我们了解了如何为Scrapy爬虫设置代理,接下来的一个话题便是如何获取代理服务器。如果你感觉购买云服务器(亚马逊云或阿里云服务器等)自行搭建代理服务器的成本太高(但可靠、可控),那么可以通过google或baidu找到一些提供免费代理服务器信息的网站,例如:
http://proxy-list.org(国外)
https://free-proxy-list.net(国外)
http://www.xicidaili.com
http://www.proxy360.cn
http://www.kuaidaili.com
以http://www.xicidaili.com为例,图13-3所示为该网站“国内高匿代理”分类下的页面。
图13-3
从中可以看出,该网站提供了大量的免费代理服务器信息,如果只需要少量的代理,从中选择几个就可以了,不过通常直觉告诉我们“多多益善”。接下来编写爬虫,爬取“国内高匿代理”分类下前3页的所有代理服务器信息,并验证每个代理是否可用。
创建Scrapy项目,取名为proxy_example:
$ scrapy startproject proxy_example
该网站会检测用户发送的HTTP请求头部中的User-Agent字段,因此我们需要伪装成某种常规浏览器,在配置文件添加如下代码:
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/41.0.2272.76'
实现XiciSpider爬取代理服务器信息,并过滤不可用代理,代码如下:
# -*- coding: utf-8 -*- import scrapy from scrapy import Request import json class XiciSpider(scrapy.Spider): name = "xici_proxy" allowed_domains = ["www.xicidaili.com"] def start_requests(self): #爬取http://www.xicidaili.com/nn/前3 页 foriin range(1, 4): yield Request('http://www.xicidaili.com/nn/%s' % i) def parse(self, response): for sel in response.xpath('//table[@id="ip_list"]/tr[position()>1]'): # 提取代理的IP、port、scheme(http or https) ip = sel.css('td:nth-child(2)::text').extract_first() port = sel.css('td:nth-child(3)::text').extract_first() scheme = sel.css('td:nth-child(6)::text').extract_first().lower() # 使用爬取到的代理再次发送请求到http(s)://httpbin.org/ip,验证代理是否可用 url = '%s://httpbin.org/ip' % scheme proxy = '%s://%s:%s' % (scheme, ip, port) meta = { 'proxy': proxy, 'dont_retry': True, 'download_timeout': 10, # 以下两个字段是传递给check_available 方法的信息,方便检测 '_proxy_scheme': scheme, '_proxy_ip': ip, } yield Request(url, callback=self.check_available, meta=meta, dont_filter=True) def check_available(self, response): proxy_ip = response.meta['_proxy_ip'] # 判断代理是否具有隐藏IP 功能 if proxy_ip == json.loads(response.text)['origin']: yield { 'proxy_scheme': response.meta['_proxy_scheme'], 'proxy': response.meta['proxy'], }
解释上述代码如下:
在start_requests方法中请求http://www.xicidaili.com/nn下的前3页,以parse方法作为页面解析函数。
在parse方法中提取一个页面中所有的代理服务器信息,这些代理未必都是可用的,因此使用爬取到的代理发送请求到http(s)://httpbin.org/ip验证其是否可用,以check_available方法作为页面解析函数。
能执行到check_available方法,意味着response对应请求所使用的代理是可用的。在check_available方法中,通过响应json串中的origin字段可以判断代理是否是匿名的(隐藏ip),返回匿名代理。
运行爬虫,将可用的代理服务器保存到json文件中,供其他程序使用:
$ scrapy crawl xici_proxy -o proxy_list.json ... $ cat proxy_list.json [ {"proxy": "http://110.73.10.37:8123", "proxy_scheme": "http"}, {"proxy": "http://171.38.142.24:8123", "proxy_scheme": "http"}, {"proxy": "http://111.155.124.84:8123", "proxy_scheme": "http"}, {"proxy": "http://203.88.210.121:138", "proxy_scheme": "http"}, {"proxy": "http://182.88.191.195:8123", "proxy_scheme": "http"}, {"proxy": "http://121.31.151.231:8123", "proxy_scheme": "http"}, {"proxy": "http://203.93.0.115:80", "proxy_scheme": "http"}, {"proxy": "http://222.85.39.29:808", "proxy_scheme": "http"}, {"proxy": "http://175.155.25.26:808", "proxy_scheme": "http"}, {"proxy": "http://111.155.124.72:8123", "proxy_scheme": "http"}, {"proxy": "http://122.5.81.153:8118", "proxy_scheme": "http"}, {"proxy": "https://171.37.153.24:8123", "proxy_scheme": "https"}, {"proxy": "http://110.73.1.68:8123", "proxy_scheme": "http"}, {"proxy": "http://122.228.179.178:80", "proxy_scheme": "http"}, {"proxy": "http://121.31.151.226:8123", "proxy_scheme": "http"}, {"proxy": "http://171.38.171.168:8123", "proxy_scheme": "http"}, {"proxy": "http://218.22.219.133:808", "proxy_scheme": "http"}, {"proxy": "https://171.38.130.188:8123", "proxy_scheme": "https"}, {"proxy": "http://111.155.116.219:8123", "proxy_scheme": "http"}, {"proxy": "http://121.31.149.209:8123", "proxy_scheme": "http"}, {"proxy": "http://60.169.78.218:808", "proxy_scheme": "http"}, {"proxy": "http://171.38.158.227:8123", "proxy_scheme": "http"}, {"proxy": "http://121.31.150.224:8123", "proxy_scheme": "http"}, {"proxy": "http://111.155.124.78:8123", "proxy_scheme": "http"}, {"proxy": "http://182.90.83.104:8123", "proxy_scheme": "http"} ]
如结果所示,我们成功获取到了20多个可用的免费代理。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论