Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

前言

最近由于要调研一些机器学习在生物信息学方面得最新研究技术,故需要看一些相关方面的论文,这里就简单写了一个爬虫脚本,非常简单,这里使用的是Scrapy 框架

在实践的过程中遇到Unhandled error in Deferred错误,网上大多给出的答案是说由于pypiwin32的问题,可以我的pypiwin32是没有问题的,可就是一直Unhandled error in Deferred错误,很无语呀,最后我发现自己一直是屏蔽Log信息运行的即

scrapy crawl arxiv --nolog

于是乎就定位不到具体错在哪里?所以这种情况还是看一下log吧

scrapy crawl arxiv

最后定位到是piplines.py文件出错啦,总之我想说的是,遇到Unhandled error in Deferred问题的时候,也许是piplines.py出错啦,应该检查一下的

本文适合刚入门同学

采用的是循序渐进的方式进行演示,直到最终目的,对Scrapy的各个文件作用都进行了演示对比

全部代码:https://github.com/Mryangkaitong/python_Crawler/tree/master/MolMachineLearning

正文

第一阶段

要爬取的网站是https://arxiv.org/list/cs.LG/recent

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

下载的很简单啦,笔者这里使用的是anaconda

conda install Scrapy

安装好后,打开cmd ,输入scrapy 测试一下:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

关于 Scrapy的介绍:这里不再详细介绍 推荐:

入门博客:https://www.runoob.com/w3cnote/scrapy-detail.html

Scrapy英文文档:https://doc.scrapy.org/en/latest/topics/spiders.html

Scrapy中文文档:https://oner-wv.gitbooks.io/scrapy_zh/content/?q=

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

下面开始我们的小项目:

首先创建一个叫做MolMachineLearning的项目

scrapy startproject MolMachineLearning

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

创建好后进去到我们项目的文件夹下

cd MolMachineLearning

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

其下目录结构大概是这样:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

接着我们就开始生成爬虫文件:

scrapy genspider arxiv "arxiv.org"

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

可以看到在spiders文件夹下已经生成好了我们的爬虫文件

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

编写数据结构items.py

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

 

编写爬虫文件arxiv.py

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

当然了,我们可以创建多个spiders

可以使用

scrapy list

来查看我们已经创建了的那些spiders

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

我们这里手动将start_urls改为我们目标的网址:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

然后改写parse部分:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

关于这里的Xpath怎么写,可以去看一下教程,或者还有一个方法,就是直接打开chome浏览器的开发工具下的elements

右键想要得到的Xpath处,选择Copy下的 Copy XPath即可得到

 

到此我们就算编写好爬虫文件啦!!

接着编写pipelines.py文件

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

这部分遇到两个问题:

开始的时候笔者是这样写的(错误的):

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

对比前后有两个不同,首先open的地方没有加上r

其次使用了utf8编码

导致的错误如下:

如果不加r那么路径会翻译转移字符\

第二个加了utf8后,笔者发现最后生成的txt文件中什么都没有,即数据没有写进txt文件中,去掉编码就可以啦,具体原因还不太清楚。

最后配置settings.py

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

这个的目的就是激活pipelines.py文件中的process_item函数执行,如果不配置,那么实际上pipelines.py是不会运行的

最后就是运行就可以啦:

scrapy crawl arxiv --nolog

 

注意是在如下目录下打开cmd运行的

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

结果:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

第二阶段:

现在我们在第一阶段提取了论文题目,接下来要完成的目标是下载这些论文,框架的话还是和上面一样,这里简单说一下不同点吧:

一 :增加了一个url字段

items.py和arxiv.py修改如下

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

二 :使用了文件下载器FilesPipeline

pipelines.py修改如下

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

需要强调的是这里重写了一个类DownloadPapersPipeline,其重载了FilesPipeline,同时需要注意的是:

for paper_url in item['url']:

这句话中item['url']并不是我们理解的是由好多urls组成的,而是一个个单独的,所以在arxiv.py提取url字段的时候特意给其加了一个列表的形式,即如果不加这里[],那么比如对于一个url:https://arxiv.org/pdf/1904.05876.pdf,经过for paper_url in item['url']后提取出来的就是h啦,加上列表[https://arxiv.org/pdf/1904.05876.pdf],那么提取出来的就是正确的url啦,具体原因就是:pipelines.py文件是管道文件,它的执行不是等爬虫文件(arxiv)执行完,Item保存了所有数据,而是爬虫程序处理完一条数据后就会送到管道文件执行,所以送过去的是一条数据(理解有误,还望指正),总之想说的就是加[]

三 :设置配置文件

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

激活管道中相应的该类,同时设置pdf保存文件的路径。

运行结果:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

会看到多了一个full文件,打开该文件:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

已经下载好我们的文件啦,但是现在还有一个问题就是文件名不是我们想要的形式

我们可以利用我们提取的name字段来命名,需要注意的是:在win环境下文件名命名中是不允许有/ \ : * ? " < > |符号的,而从上面的例子中可以看到我们的论文题目中显然有的有冒号,于是我们要去掉这些特殊符号,方法多多,笔者这里用的就是re模块,不多解释啦,不是本文重点,感兴趣的可以百度一下

修改pipelines.py如下:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

运行结果:

 

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

第三阶段:

如果你是想看看机器学习在各个领域的应用或者最近发表的机器学习文章有哪些?其实上面的例子就已经满足啦,可是假如我们只想获取某一方向的机器学习论文呢?那么我们就不得不进行一下筛选啦,假设我们现在只想要和深度学习有关的文章那么我们可以筛选题目中含有Deep的,当然了,为了使范围更广,我们可以多加关键字,比如通常CNN和RNN依据LSTM等等都是深度学习方面的论文,接下来我们就来干这件事情:

piplines.py修改如下:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

可以看到,这里仅仅增加了红色框的部分,只有满足的item才会被返回,否则丢弃

settings.py修改如下:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

需要说明的是:和之前对比,这里的又300 1 变为1和300 其实数字本身无多大意义,关键是相对大小,数字越小运行的优先级越高,这里将MolmachinelearningPipeline的优先级高于DownloadPapersPipeline即MolmachinelearningPipeline先运行,由于其内部实现了对item的过滤,过滤掉的数据之后不再传输给其他管道程序,所以MolmachinelearningPipeline中的item是过滤后的Item,达到我们的目的

运行结果:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

结果下载的就只有深度学习方面的论文啦,注意这里是否能够精确的定位到你想要的论文的关键在于re模块正则化的应用,和爬虫本身并没有多大关系,为此这里不多这方面的解释啦

第四阶段:

做到这里,其实还没有结束,我们上面爬取的其实仅仅是一个页面的数据

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

而我们是想把347最近的347篇都爬下来,怎么办呢?最通常的做法就是递归爬取

即在爬虫文件下的parse函数下加上

 urls = response.xpath('你的页数部分Xpath/@href').extract()
    for url in urls:
        yield Request(url, callback=self.parse)

但是笔者这里比较特殊:

会发现这里并不是全部显示,中间还有...,导致解析出来后是..,得不到这部分论文,解决的方法比较多,首先该网站做的比较好,可以通过点击more来增大步数,想这样:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

还有就是点击all,即全部显示,这时候我们看一下其网址:

https://arxiv.org/list/cs.LG/pastweek?show=347

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

其实按月进行分割的

爬虫文件修改如下:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

运行结果:

Python Scrapy 爬取论文以及解决Unhandled error in Deferred问题

结束语:

其实即使全部下载下来也才300来篇,没有必要进行筛选,但是一旦数据量多了起来,其实第四阶段所做的事情还是很有必要的,这里之所以这么做是想尽可能的展现Scrapy的用法。

本文的主要目的:

通过本demo展现一下简单的框架即:

items.py : 是数据结构,类似一个字典

spiders文件夹下的arxiv.py  : 是爬虫文件,具体的名字可以根据自己的需要进行定义

pipelines.py :管道文件,负责对爬取的数据进行处理包括过滤,保存,下载等等

settings.py : 配置文件,其中比较关键的作用是是激活管道文件的运行

 

 

上一篇:unity渲染路径


下一篇:Linux framebuffer deferred io机制