Python 爬虫:Scrapy 实例(三)

2019 年 8 月 23 日 计算机与网络安全

一次性付费进群,长期免费索取教程,没有费教程。

教程列表见微信公众号底部菜单

微信群回复公众号:微信群QQ群460500587

微信公众号:计算机与网络安全

ID:Computer-network


本文将从网站上获取免费的代理服务器。使用Scrapy获取代理服务器后,一一验证哪些代理服务器可用,最终将可用的代理服务器保存到文件。


首先要做的是找到免费代理服务器的来源。浏览器中打开百度,搜索“免费代理服务器”。

先在www.proxy360.cn中获取代理服务器。如果数量不够,可以在www.xicidaili.com中获取代理服务器

在浏览器中打开这两个站点,观察所需的项目。发现大部分的项目都相同,共有的项目有服务器IP、服务器端口、是否匿名、服务器位置。xicidaili站点中独有的项有服务协议。最后还应该添加获取服务器的来源站点。知道了这些内容,items.py文件基本已经出来了。

1、创建编辑Scrapy爬虫

打开Putty连接到Linux。在工作目录下创建Scrapy项目,并根据提示依照spider基础模版创建一个spider。执行命令:

cd
cd code/scrapy
scrapy startproject getProxy
cd getProxy
scrapy genspider proxy360Spider proxy360.cn

这里创建了一个名为getProxy的Scrapy项目,并创建了一个名为proxy360Spider.py的Spider文件。

(1)修改items.py

items.py包含6项。items.py文件内容如下:

1 # -*- coding: utf-8 -*-

2

3 # Define here the models for your scraped items

4 #

5 # See documentation in:

6 # http://doc.scrapy.org/en/latest/topics/items.html

7

8 import scrapy

9

10

11 class GetproxyItem(scrapy.Item):

12     # define the fields for your item here like:

13     # name = scrapy.Field()

14      ip = scrapy.Field()

15      port = scrapy.Field()

16      type = scrapy.Field()

17      loction = scrapy.Field()

18      protocol = scrapy.Field()

19      source = scrapy.Field()

需要几项,就填入几项。最简模式就是只要代理IP和端口。这个文件没什么好解释的,比较简单直白。

(2)修改Spider文件proxy360Spider.py

先把proxy360Spider.py文件放到一边。使用scrapy shell命令查看一下连接网站返回的结果和数据,进入getProxy项目下的任意目录下,执行命令:

scrapy shell http://www.proxy360.cn/Region/China

执行结果如图1所示。

图1  scrapy shell

从response的返回代码可以看出request请求正常返回。再查看一下response的数据内容,执行命令:

response.xpath('/*').extract()

执行结果如图2所示。

图2  response数据

返回的数据中含有代理服务器(难道返回代码为200时,还有返回数据不含代理服务器的吗?这个还真有)。测试一下如何使用选择器在response中的得到所需的数据。在浏览器中打开http://www.proxy360.cn/Region/China,在网页的任意空白处右击,选择“查看网页源代码”,打开页面的源代码网页,如图3所示。

图3  页面源代码

观察一下,似乎所有的数据块都是以<div class="proxylistitem" name="list_proxy_ip">这个tag开头的。在scrapy shell中测试一下,回到scrapy shell中,执行命令:

subSelector=response.xpath('/div[@class="proxylistitem" and @name="list_proxy_ip"]')
subSelector.xpath('.//span[1]/test()').extract()[0]
subSelector.xpath('.//span[2]/test()').extract()[0]
subSelector.xpath('.//span[3]/test()').extract()[0]
subSelector.xpath('.//span[4]/test()').extract()[0]

执行结果如图4所示。

图4  proxy360Spider测试选择器

所得数据左右两侧都有很多的空格。

现在如何用选择器从response中获取所需数据的方法也出来了,接下来可以开始编写Spider文件proxy360Spider.py。proxy360Spider.py的内容如下:

1 # -*- coding: utf-8 -*-

2 import scrapy

3 from getProxy.items import GetproxyItem

4

5 class Proxy360Spider(scrapy.Spider):

6     name = "proxy360Spider"

7     allowed_domains = ["proxy360.com"]

8     nations=['Brazil','China','America','Taiwan','Japan','Thailand','Vietnam','bahrein']

9     start_urls = []

10     for nation in nations:

11         start_urls.append('http://www.proxy360.cn/Region/' + nation)

12

13

14     def parse(self, response):

15         subSelector = response.xpath('//div[@class="proxylistitem" and @name="list_proxy_ip"]')

16         items = []

17         for sub in subSelector:

18             item = GetproxyItem()

19             item['ip'] = sub.xpath('.//span[1]/text()').extract()[0]

20             item['port'] = sub.xpath('.//span[2]/text()').extract()[0]

21             item['type'] = sub.xpath('.//span[3]/text()').extract()[0]

22             item['loction'] = sub.xpath('.//span[4]/text()').extract()[0]

23             item['protocol'] = 'HTTP'

24             item['source'] = 'proxy360'

25             items.append(item)

26         return items


在http://www.proxy360.cn/Region/China页面中并没有显示服务器使用的协议。一般都是HTTP协议,所以item['protocol']统一设置成了HTTP。而数据来源都是proxy360网站,item['source']都设置成了proxy360。

(3)修改pipelines.py,处理Spider的结果

这里还是将Spider的结果保存为txt格式,以便于阅读。pipelines.py文件内容如下:

1 # -*- coding: utf-8 -*-

2

3 # Define your item pipelines here

4 #

5 # Don't forget to add your pipeline to the ITEM_PIPELINES setting

6 # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html

7

8 import codecs

9

10 class GetproxyPipeline(object):

11     def process_item(self, item, spider):

12         fileName = 'proxy.txt'

13         with codecs.open(fileName, 'a', 'utf-8') as fp:

14             fp.write("{'%s': '%s://%s:%s'}||\t %s \t %s \t %s \r\n"

15             %(item['protocol'].strip(), item['protocol'].strip(),item['ip'].strip(),item['port'].strip(),item['type'].strip(),item['loction'].strip(),item['source'].strip()))

16         return item

在14行中加入了两条竖线,是为了以后能方便地将代理字典({'http':'http://1.2.3.4:8080'})从字符串中分离出来。在15行中,写入文件时使用了strip()函数去除所得数据左右两边的空格。


(4)修改settings.py,决定由哪个文件来处理获取的数据

settings.py稍作修改即可。将pipelines.py添加到ITEM_PIPELINES中去就能解决问题。settings.sp文件内容如下:

1 # -*- coding: utf-8 -*-

2

3 # Scrapy settings for getProxy project

4 #

5 # For simplicity, this file contains only the most important settings by

6 # default. All the other settings are documented here:

7 #

8 #     http://doc.scrapy.org/en/latest/topics/settings.html

9 #

10

11 BOT_NAME = 'getProxy'

12

13 SPIDER_MODULES = ['getProxy.spiders']

14 NEWSPIDER_MODULE = 'getProxy.spiders'

15

16 # Crawl responsibly by identifying yourself (and your website) on the User-Agent

17 #USER_AGENT = 'getProxy (+http://www.yourdomain.com)'

18

19

20 ### user add

21 ITEM_PIPELINES = {

22 'getProxy.pipelines.GetproxyPipeline':100

23 }


最后回到项目getProxy目录下,执行命令:

scrapy crawl proxy360Spider
ls
wc -l proxy.txt
more proxy.txt

执行结果如图5所示。

图5  scrapy crawl proxy360Spider

得到的结果没什么问题。可花了这么长时间最后只得到了144个数据的结果,效率也太低了点吧。不过没关系,再给它一个Spider就可以了,一个站点的数据不够就再加一个站点。如果还不够,就继续增加站点吧!

2、多个Spider

按照一个Spider的思路,得到的proxy数据不够多,则可以在www.xicidaili.com中获取代理补足。到项目getProxy目录下,执行命令:

cd
cd code/scrapy
cd getProxy
scrapy genspider xiciSpider xicidaili.com

创建一个名为xiciSpider.py的Spider文件。items.py无须修改了,直接对xiciSpider.py做修改就可以了。我们还是先用scrapy shell命令来确定如何获取数据,执行命令:

scrapy shell http://www.xicidaili.com/nn/2

得到的结果如图6所示。

图6  scrapy shell

这里发现一个问题。respnose返回的代码是500,要知道返回码是200才是正常返回。在浏览器中打开http://www.xicidaili.com/nn/2是正常显示的,而该网页并不需要登录,那就是说并不涉及cookie。用scrapy shell请求页面和用浏览器请求页面用的是同一IP。也不存在IP封锁的问题。剩下的就只有headers中User-Agent的问题了。除去所有的不可能,最后那一选项大致就是正确答案。

在Scrapy中的确是有默认的headers,但这个headers与浏览器的headers是有区别的。有的网站会检查headers,如果是正常浏览器的headers网站则予以通过,而机器人或者说爬虫的headers则拒绝访问。所以在这里只需要给scrapy一个浏览器的headers就可以解决问题了。修改settings.py文件内容如下:

1 # -*- coding: utf-8 -*-

2

3 # Scrapy settings for getProxy project

4 #

5 # For simplicity, this file contains only the most important settings by

6 # default. All the other settings are documented here:

7 #

8 #     http://doc.scrapy.org/en/latest/topics/settings.html

9 #

10

11 BOT_NAME = 'getProxy'

12

13 SPIDER_MODULES = ['getProxy.spiders']

14 NEWSPIDER_MODULE = 'getProxy.spiders'

15

16 # Crawl responsibly by identifying yourself (and your website) on the User-Agent

17 #USER_AGENT = 'getProxy (+http://www.yourdomain.com)'

18

19

20 ### user add

21 USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36(KHTML, like Gecko)'

22 ITEM_PIPELINES = {

23 'getProxy.pipelines.GetproxyPipeline':100

24 }

只需要在settings.py里添加一个USER_AGENT项就可以了。如果可以,尽可能使用本机浏览器的headers。这里使用的是随意选取的一个headers,好在该网站没有根据不同的headers返回不同的内容。

再回到getProxy项目的目录下,使用scrapy shell测试如何获取有效数据。执行命令:

scrapy shell http://www.xicidaili.com/nn/2



得到的结果如图7所示。

图7  修改headers后scrapy shell

如图7所示,response的返回码为200,现在没问题了。浏览器中打开http://www.xicidaili.com/nn/2,空白处右击,选择“查看网页源代码”,打开了页面的源代码网页,发现所需数据的块都是以<tr class="odd">或者<tr class="">开头的。在scrapy shell中执行命令:

subSelector=response.xpath('//tr[@class=""]|//tr[@class="odd"]')
subSelector[0].xpath('.//td[2]/test()').extract()[0]
subSelector[0].xpath('.//td[3]/test()').extract()[0]
subSelector[0].xpath('.//td[4]/test()').extract()[0]
subSelector[0].xpath('.//td[5]/test()').extract()[0]
subSelector[0].xpath('.//td[6]/test()').extract()[0]

执行结果如图8所示。

图8  xiciSpider测试选择器

现在xiciSpider.py怎么编写已经一目了然了。xiciSpider.py的内容如下:

回到项目getProxy目录下,执行命令:

scrapy crawl xiciSpider
ls
wc -l proxy.txt

执行结果如图9所示。

图9  scrapy crawl xiciSpider

xicidaili.com同一IP,短时间内频繁爬取,超过一定次数就会被封锁IP。万一被封锁了,那就重启路由器或者光猫换个IP吧。

从文件保存的记录数字来看,应该是没问题的。但这么多的记录,或者说这么多的代理服务器有多少是可用的呢?

3、处理Spider数据

如何来验证上面已经获取到的代理服务器地址,最简单的方法当然是在pipelines文件里直接修改。但不幸的是验证一个代理服务器是否有效所需的时间和将一行记录写入文件的时间相差得太远了。前者所需的时间是以秒计算的,后者是以微秒计算。这样一来还不如先将所有的代理服务器保存到文件,然后另外写一个Python程序来验证代理。

进入getProxy项目的目录下,创建Python验证程序。执行命令:

cd
cd code/scrapy
cd getProxy
vi connWebWithProxy.py

代理服务器验证程序connWebWithProxy.py的内容如下:

执行命令:

python3 connWebWithProxy.py

利用多线程来验证来源文件proxy.txt里的代理。经过验证,有181个代理可以使用。将self.threads设置为10,使用10个进程并发,大概需要1分钟左右,速度还可以接受。这个速度已经很快了,没有必要将self.threads设置得太大,以免占用太多的系统资源。最终得到文件alive.txt。这个程序还比较简陋,有很大的改进空间。例如,同一网站下爬取的代理服务器也许不会有重复的情况,但多个网站爬取的代理服务器就有可能重复。这种情况可以在程序内加上一个去重的函数

微信公众号:计算机与网络安全

ID:Computer-network


【推荐书籍】
登录查看更多
1

相关内容

Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
190+阅读 · 2020年6月29日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
229+阅读 · 2020年5月21日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
115+阅读 · 2020年5月10日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
223+阅读 · 2020年3月22日
【资源】100+本免费数据科学书
专知会员服务
105+阅读 · 2020年3月17日
算法与数据结构Python,369页pdf
专知会员服务
160+阅读 · 2020年3月4日
用 Python 开发 Excel 宏脚本的神器
私募工场
26+阅读 · 2019年9月8日
一个牛逼的 Python 调试工具
机器学习算法与Python学习
15+阅读 · 2019年4月30日
GitHub 热门:各大网站的 Python 爬虫登录汇总
机器学习算法与Python学习
9+阅读 · 2019年3月20日
我是一个爬虫
码农翻身
12+阅读 · 2018年6月4日
干货 | Python 爬虫的工具列表大全
机器学习算法与Python学习
10+阅读 · 2018年4月13日
Python机器学习教程资料/代码
机器学习研究会
8+阅读 · 2018年2月22日
用Python调用百度OCR接口实例
数据挖掘入门与实战
16+阅读 · 2018年1月29日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
Python NLP 入门教程
开源中国
14+阅读 · 2017年10月1日
Learning to See Through Obstructions
Arxiv
7+阅读 · 2020年4月2日
Arxiv
91+阅读 · 2020年2月28日
Arxiv
34+阅读 · 2019年11月7日
Embedding Logical Queries on Knowledge Graphs
Arxiv
3+阅读 · 2019年2月19日
Arxiv
9+阅读 · 2018年3月23日
Arxiv
5+阅读 · 2018年1月17日
VIP会员
相关VIP内容
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
190+阅读 · 2020年6月29日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
229+阅读 · 2020年5月21日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
115+阅读 · 2020年5月10日
【干货书】流畅Python,766页pdf,中英文版
专知会员服务
223+阅读 · 2020年3月22日
【资源】100+本免费数据科学书
专知会员服务
105+阅读 · 2020年3月17日
算法与数据结构Python,369页pdf
专知会员服务
160+阅读 · 2020年3月4日
相关资讯
用 Python 开发 Excel 宏脚本的神器
私募工场
26+阅读 · 2019年9月8日
一个牛逼的 Python 调试工具
机器学习算法与Python学习
15+阅读 · 2019年4月30日
GitHub 热门:各大网站的 Python 爬虫登录汇总
机器学习算法与Python学习
9+阅读 · 2019年3月20日
我是一个爬虫
码农翻身
12+阅读 · 2018年6月4日
干货 | Python 爬虫的工具列表大全
机器学习算法与Python学习
10+阅读 · 2018年4月13日
Python机器学习教程资料/代码
机器学习研究会
8+阅读 · 2018年2月22日
用Python调用百度OCR接口实例
数据挖掘入门与实战
16+阅读 · 2018年1月29日
教你用Python来玩跳一跳
七月在线实验室
6+阅读 · 2018年1月2日
Python3爬虫之入门和正则表达式
全球人工智能
7+阅读 · 2017年10月9日
Python NLP 入门教程
开源中国
14+阅读 · 2017年10月1日
Top
微信扫码咨询专知VIP会员