Scrapy学习笔记-Scrapy入门之创建爬虫

Creating a project

在开始抓取之前,您将必须设置一个新的Scrapy项目。 输入您要存储代码并运行的目录:scrapy startproject tutorial
Anacoda下使用
在这里插入图片描述

这将创建一个包含以下内容的教程目录:
在这里插入图片描述

Spiders是您定义的类,Scrapy用于从网站(或一组网站)中获取信息。 他们必须继承Spider的子类,并定义要发出的初始请求,可以选择如何跟随页面中的链接,以及如何解析下载的页面内容以提取数据。
这是我们第一个Spider的代码。 将其保存在项目中tutorial/spiders目录下的一个名为quotes_spider.py的文件中:

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = 'quotes-%s.html' % page
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log('Saved file %s' % filename)

在这里插入图片描述
QuotesSpider类将scrapy.Spider作为父类,并定义了一些属性和方法:
name用于识别Spide,它在一个项目中必须是唯一的,也就是说,您不能为不同的Spider设置相同的名称。
start_requests()必须返回一个可迭代的请求(您可以返回一个请求列表或编写一个生成器函数),Spider将从中开始爬行。 随后的请求将根据这些初始请求连续生成。
parse()一个将被调用以处理针对每个请求下载的响应的方法。 response参数是TextResponse的一个实例,该实例保存页面内容并具有其他有用的方法来处理它。parse方法通常解析响应,提取刮取的数据作为字典,还查找要遵循的新URL并从中创建新请求(Request)。
在这里插入图片描述

run spider

要使我们的蜘蛛工作,请转到项目的顶级目录并运行:scrapy crawl quotes
在这里插入图片描述
检查当前目录中的文件。 您应该注意,已经创建了两个新文件:quotes-1.html和quotes-2.html,其中包含我们URL的内容,正如我们的parse方法所指示的那样。
在这里插入图片描述

在这里插入图片描述
Scrapy调度Spider的start_requests方法返回的scrapy.Request对象。 在收到每个响应时,它实例化Response对象并调用与请求关联的回调方法(在本例中为parse方法),并将响应作为参数传递。

A shortcut to the start_requests method

无需实现从URL生成scrapy.Request对象的start_requests方法,只需定义带有URL列表的start_urls类属性即可。 然后,Scrapy提供的start_requests默认实现将使用此列表来为您的蜘蛛创建初始请求。

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = 'quotes-%s.html' % page
        with open(filename, 'wb') as f:
            f.write(response.body)

即使我们没有明确告诉Scrapy这样做,也会调用parse方法来处理这些URL的响应。 发生这种情况是因为parse是Scrapy的默认回调方法,对于没有显式分配的回调的请求会调用该方法。

scrapy shell

学习如何使用Scrapy提取数据的最佳方法是使用Scrapy shell尝试选择器。请记住,从命令行运行Scrapy shell时,始终将网址括在引号中,否则包含参数(即&字符)的网址将不起作用。
scrapy shell ‘http://quotes.toscrape.com/page/1/’
在Windows上,请使用双引号代替:
scrapy shell “http://quotes.toscrape.com/page/1/”
在这里插入图片描述
在这里插入图片描述

CSS选择器

使用shell,您可以尝试使用带有响应对象的CSS选择元素:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行response.css(‘title’)的结果是一个名为SelectorList的类似列表的对象,该对象表示围绕XML / HTML元素的Selector对象的列表,并允许您运行进一步的查询来细化选择或提取内容数据。
在这里插入图片描述
这里有两点需要注意:一是我们在CSS查询中添加了:: text,这意味着我们只想直接在<title>元素内选择text元素。 如果不指定:: text,则会获得完整的title元素,包括其标签:
在这里插入图片描述
另一件事是,调用.getall的结果是一个列表:选择器有可能返回多个结果,因此我们将它们全部提取出来。 当您知道只想要第一个结果时,在这种情况下,您可以执行以下操作:
在这里插入图片描述
在这里插入图片描述
但是,直接在SelectorList实例上使用.get()可以避免IndexError,并且在找不到与选择匹配的任何元素时返回None。这里有一个教训:对于大多数抓取代码,您希望它能够抵抗由于页面上找不到内容而导致的错误,因此即使某些部分未能被抓取,您也至少可以获取一些数据。

除了getall和get方法之外,您还可以使用re方法使用正则表达式进行提取:
在这里插入图片描述
在这里插入图片描述
为了找到合适的CSS选择器,您可能会发现使用view(response)从Web浏览器的外壳中打开响应页面很有用。 您可以使用浏览器的开发人员工具检查HTML并提供一个选择器(请参阅使用浏览器的开发人员工具进行抓取)。

Selector Gadget还是一个不错的工具,可以快速为视觉选择的元素找到CSS选择器,该选择器可在许多浏览器中使用。

获得带quote的class的div标签:

<div class="quote">
    <span class="text">“The world as we have created it is a process of our
    thinking. It cannot be changed without changing our thinking.”</span>
    <span>
        by <small class="author">Albert Einstein</small>
        <a href="/author/Albert-Einstein">(about)</a>
    </span>
    <div class="tags">
        Tags:
        <a class="tag" href="/tag/change/page/1/">change</a>
        <a class="tag" href="/tag/deep-thoughts/page/1/">deep-thoughts</a>
        <a class="tag" href="/tag/thinking/page/1/">thinking</a>
        <a class="tag" href="/tag/world/page/1/">world</a>
    </div>
</div>

我们获得带有 quote HTML elements的选择器的列表,其中包括:
在这里插入图片描述
在这里插入图片描述
上面的查询返回的每个选择器都允许我们在其子元素上运行进一步的查询。 让我们将第一个选择器分配给变量,以便我们可以直接在特定引号上运行CSS选择器:
在这里插入图片描述
获得带tags的class修饰的div下的带tag的class的子标签的text内容,使用.getall()方法获取所有这些。
在这里插入图片描述

XPath

在这里插入图片描述
在这里插入图片描述
XPath表达式非常强大,并且是Scrapy Selectors的基础。 实际上,CSS选择器是在后台转换为XPath的。 您可以看到,如果您仔细阅读外壳中选择器对象的文本表示形式。尽管XPath表达式可能不如CSS选择器流行,但它提供了更多功能,因为除了导航结构之外,它还可以查看内容。 使用XPath,您可以选择以下内容:选择包含文本“下一页”的链接。 这使XPath非常适合于抓取任务,并且即使您已经知道如何构造CSS选择器,我们也鼓励您学习XPath,这将使抓取更加容易。

案例

提取每个博客的url地址:https://blog.csdn.net/asmartkiller
在这里插入图片描述
body标签下->class=“container clearfix pt0” id="mainBox"的div->main->class="article-list"的div->每篇文章对应一个class=“article-item-box csdn-tracking-statistics”的div->h4->a标签的href属性。
使用scrapy shell提取各个博客的URL地址
使用css选择器的class选中包含每篇文章的url的Selector对象的列表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用xpath选择器的class选中包含每篇文章的url的Selector对象的列表

在这里插入图片描述

import scrapy

class blogsSpider(scrapy.Spider):
    name = "blogs"
    start_urls = [
        'https://blog.csdn.net/asmartkiller/article/list/1',
    ]

    def parse(self, response):
        for res in response.css('.article-item-box'):
            yield {
                'blogurl': res.css('h4').css('a').attrib['href'],
            }

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后面将介绍处理分页
在这里插入图片描述
在这里插入图片描述

总结

关于初始URL的使用:带有URL列表的start_urls类属性或实现从URL生成scrapy.Request对象的start_requests方法

start_urls = ['http://quotes.toscrape.com/page/1/', 'http://quotes.toscrape.com/page/2/',]

def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

关于处理响应的回调方法:parse是Scrapy的默认回调方法,对于没有显式分配回调函数的请求会调用该方法。

猜你喜欢

转载自blog.csdn.net/asmartkiller/article/details/105563319