scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

1、scrapy工作路径

     简单说明:首先,engine从start_url或者自定义的start_requests()中获得初始的url,url通过请求得到response,如果没有设置callback回调给函数,则默认回调给parse(),如果设置则回调给相应的函数。此时response中包括已经成型的数据以及一些链接。已经成型的数据可以直接传给Item并yield或return给Pipeline保存或者直接导出,而生成的链接可通过callback再次回调给相应的函数,从而解析获得的链接的内容。以此往复,从而通过初始的url一步步实现网站深度与广度的爬取。

2、response的解析

常用Xpath与CSS,本人一般使用CSS。所以在此只列CSS选择器。

经过请求得到的response回调给了相应的函数,此时通过对response的解析便可以得到想要的数据及之后的url。

response.css(‘选定内容的CSS表达式’)        CSS选择器用法稍后列出  

此时有两个内容需要记住:文本提取,选择表达式后加  ::text

                                            属性提取,选择表达式和加  ::attr('属性名')

通CSS选择器选择后,可通过extract_first() 与extract将其中的内容提取出来。其中extract_first()提取单个,extract提取全部,返回结果为列表。

         CSS选择器用法记录,记录可能会经常用的几种

       *                                                                                  选取所有元素

    class='intro'                       .intro                             选取class为intro的元素

    id = "first_name"               #first_name                   选取id为first_name的元素

   <p>                                        p                                    直接用相应标签元素表示

 <p>,<img>                               p,img                            选取所有<img>与<p>

                                                  a  img                             选取a标签内部的img标签

                                                  [target=  blue]                  选取target属性为blue的所有元素

                                                   a[target= blue]                选取target属性为blue的所有a元素

                                                  [title~=flower]                   选取title属性中包含“flower”的所有元素

                                                    p:first-letter                      选择每个P元素的首字母

                                                     p:first-line                        选择每个P元素的首行

                                                    p:first-child                        选择同为子元素的P里边的第一个P

                                                    p:nth-child(2)                    选择同为子元素的P里边的第2个P

                                                   p:nth-last-child(2)             选择同为子元素的P里边的倒数第二个P(选择下一页标签时经常使用)

                                                     p:last-child                         选择同为子元素的最后一个P

示例

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

可以看到PageNum的html标签都在上边,其li的class均为page-item,a的class均为page-link,此时如果我们想一直点下一页,应该选择最后一个li标签里的a标签的href属性。 可以写为  response.css(ul.pagination li:last-child a::attr("href")).extract_first()  或者通过选择用倒数第一个元素的方式也可以。其大概描述为选择class为pagination的ul元素里的最后一个li里的a元素的href属性,并将其提取出来。 属性值只有一个,用extract_first()。如果下一页标签在倒数第二个li里边则可以用 p:nth-last-child(2) 。

3、 此时数据与URL的提取已经不是问题,下一步应该是将数据导出或者保存至数据库或者直接下载。

3.1数据的直接导出:

scrapy crawl + 爬虫的名称         -o   文件名.格式                如:     scrapy crawl   quotes    -o     quotes.csv

或者还可以导出为xml,json等格式。

数据的保存:

通过处理完response后我们一般将我们想要保存下来的数据存入item中,通过yield或者return我们便将item 传给了Pipeline,因此,数据的数据库保存还有数据的下载,均在Pipeline中配置。

3.2 数据的下载配置(以图片下载配置为例)

scrapy中的ImagesPipeline负责实现下载功能,因此我们需要创建自己的Pipeline并且继承ImagePipeline

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)      一般自己的Pipeline名称,scrapy会自己创建好,即scrapy项目文件名,首字母大写后 加Pipeline。一般图片下载分为三步(三个函数),1、从相应的item中取出相应下载的图片的url,通过request发出请求。2、创建图片保存后的名字 3、当图片无法下载时做异常处理的。

代码如下:首先通过 if     isinstance(item,选定的item名称 )选定自己要在此处下载的内容所在的item。这是设置了多个item时需要做的。如果只有一个item则不需要。其代码如下下:   因为item['pic_urls']中包含的是一个图片的列表,因此需要遍历这个列表然后发送请求。 同时需要 注意的时需要导入相应的模块。如Request、以及你的Item、 ImagePipeline还有做异常处理时的DropItem。

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

将Pipeline配置完成后,此时还不能下载。还需要在setting中,设置图片保存的文件夹的位置。以及找到ITEM_PIPELINES开启你的PIPELINES。

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

其中meitu为你的scrapy项目所在文件夹名,MeituPipeline为你自己的Pipeline名称。此时便可以开始启动项目,下载图片。

3.3 将数据保存到数据库(以MongoDB为例)

与创建图片下载的Pipeline一样,首先创建自己的MongoPIpeline,有了自己的通道,数据才能传到相应的位置。

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

首先数据库有两个初始参数,一个是数据库的uri,一个是数据将要进入的数据库名字。我们可以通过在setting中配置好相应的参数,然后抓取过来,或者直接对其赋值也可以。

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

from_cralwer为类方法,需要用@classmethod表示,可通过 crawler参数从settings拿到全局配置信息。我们可以将我们的数据库URI与数据库DB在settings中写好。然后 通过crawler抓取过来。

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

此时我们便从settings中抓到了配置好的信息。(如果觉得麻烦,也可以直接在MongoPipeline中直接定义好。)

然后我们便可以打开数据库,往数据库插入信息,最后关闭数据库。

scrapy学习总结(学自崔庆才大佬的书以及网上大佬们的博客)

                                                                                                                                                                              PS:小胖胖的猪崽