【python爬虫笔记】scrapy

目录

创建新项目

怎么用scrapy

scrapy 一个完整的案例应用

css选择器介绍

css选择器的基本语法

scrapy 中的css使用方法


0

创建新项目

 下载 scrapy

 pip install scrapy

该命令先依据 项目名 创建一个文件夹,然后再文件夹下创建于个 scrpy 项目,这一步是后续所有代码的起点。 

scrpy startproject <项目名>

创建新项目

scrapy startproject my_scrapy

 创建第一个 scrapy 爬虫文件 pm

scrapy genspider pm imspm.com

如果想要运行项目命令,则必须先进入红色下划线 my_scrapy 文件夹,在项目目录中才能控制项目。

 cd my_scrapy

此时在 spiders 文件夹中,出现 pm.py 文件,该文件内容如下所示: 

import scrapy


class PmSpider(scrapy.Spider):
    name = 'pm'
    allowed_domains = ['imspm.com']
    start_urls = ['http://imspm.com/']

    def parse(self, response):
        pass

测试 scrapy 爬虫运行
使用命令 scrapy crawl <spider>spider 是上文生成的爬虫文件名,出现如下内容,表示爬虫正确加载。

2022-11-12 15:27:02 [scrapy.utils.log] INFO: Scrapy 2.6.2 started (bot: my_scrapy)

怎么用scrapy

scrapy 工作流程非常简单:

  1. 采集第一页网页源码;
  2. 解析第一页源码,并获取下一页链接;
  3. 请求下一页网页源码;
  4. 解析源码,并获取下一页源码;
  5. […]
  6. 过程当中,提取到目标数据之后,就进行保存。

scrapy 一个完整的案例应用

> scrapy startproject my_project 爬虫
> cd 爬虫
> scrapy genspider pm imspm.com

获得项目结构如下:

python scrapy 怕学不会?看这篇就可以了。爬虫120例第42例,采集超级产品经理频道

  • scrapy.cfg:配置文件路径与部署配置;
  • items.py:目标数据的结构;
  • middlewares.py:中间件文件;
  • pipelines.py:管道文件;
  • settings.py:配置信息。

代码请求次数为 7 次,原因是在 pm.py 文件中默认没有添加 www,如果增加该内容之后,请求次数变为 4。

现在的 pm.py 文件代码如下所示:

import scrapy


class PmSpider(scrapy.Spider):
    name = 'pm'
    allowed_domains = ['www.imspm.com']
    start_urls = ['http://www.imspm.com/']

    def parse(self, response):
        print(response.text)

其中的 parse 表示请求 start_urls 中的地址,获取响应之后的回调函数,直接通过参数 response 的 .text 属性进行网页源码的输出。

获取到源码之后,要对源码进行解析与存储
在存储之前,需要手动定义一个数据结构,该内容在 items.py 文件实现,对代码中的类名进行了修改,MyProjectItem → ArticleItem

import scrapy

class ArticleItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()  # 文章标题
    url = scrapy.Field()  # 文章地址
    author = scrapy.Field()  # 作者

修改 pm.py 文件中的 parse 函数,增加网页解析相关操作,该操作类似 pyquery 知识点,直接观察代码即可掌握。

    def parse(self, response):
        # print(response.text)
        list_item = response.css('.list-item-default')
        # print(list_item)
        for item in list_item:
            title = item.css('.title::text').extract_first()  # 直接获取文本
            url = item.css('.a_block::attr(href)').extract_first() # 获取属性值
            author = item.css('.author::text').extract_first()  # 直接获取文本
            print(title, url, author)

其中 response.css 方法返回的是一个选择器列表,可以迭代该列表,然后对其中的对象调用 css 方法。

  • item.css('.title::text'),获取标签内文本;
  • item.css('.a_block::attr(href)'),获取标签属性值;
  • extract_first():解析列表第一项;
  • extract():获取列表。

在 pm.py 中导入 items.py 中的 ArticleItem 类,然后按照下述代码进行修改:

    def parse(self, response):
        # print(response.text)
        list_item = response.css('.list-item-default')
        # print(list_item)
        for i in list_item:
            item = ArticleItem()
            title = i.css('.title::text').extract_first()  # 直接获取文本
            url = i.css('.a_block::attr(href)').extract_first()  # 获取属性值
            author = i.css('.author::text').extract_first()  # 直接获取文本
            # print(title, url, author)
            # 对 item 进行赋值
            item['title'] = title
            item['url'] = url
            item['author'] = author
            yield item

此时在运行 scrapy 爬虫,就会出现如下提示信息。

python scrapy 怕学不会?看这篇就可以了。爬虫120例第42例,采集超级产品经理频道

此时完成了一个单页爬虫

接下来对 parse 函数再次改造,使其在解析完第 1 页之后,可以解析第 2 页数据。

    def parse(self, response):
        # print(response.text)
        list_item = response.css('.list-item-default')
        # print(list_item)
        for i in list_item:
            item = ArticleItem()
            title = i.css('.title::text').extract_first()  # 直接获取文本
            url = i.css('.a_block::attr(href)').extract_first()  # 获取属性值
            author = i.css('.author::text').extract_first()  # 直接获取文本
            # print(title, url, author)
            # 对 item 进行赋值
            item['title'] = title
            item['url'] = url
            item['author'] = author
            yield item
        next = response.css('.nav a:nth-last-child(2)::attr(href)').extract_first()  # 获取下一页链接
        # print(next)
        # 再次生成一个请求
        yield scrapy.Request(url=next, callback=self.parse)

上述代码中,变量 next 表示下一页地址,通过 response.css 函数获取链接,其中的 css 选择器请重点学习。

css选择器介绍

  • 在css中选择器是一种模式,用于选择需要添加样式的元素,css对html页面中的元素实现一对一,一对多或者多对一的控制,都需要用到css选择器,html页面中的元素就是通过css选择器进行控制的;

css选择器的基本语法

  • 类选择器:元素的class属性,比如class="box"表示选取class为box的元素;
  • ID选择器:元素的id属性,比如id="box"表示选取id为box的元素;
  • 元素选择器:直接选择文档元素,比如p表示选择所有的p元素,div表示选择所有的div元素;
  • 属性选择器:选择具有某个属性的元素,如*[title]表示选择所有包含title属性的元素、a[href]表示选择所有带有href属性的a元素等;
  • 后代选择器:选择包含元素后代的元素,如li a表示选取所有li 下所有a元素;
  • 子元素选择器:选择作为某元素子元素的元素,如h1 > strong表示选择父元素为h1 的所有 strong 元素;
  • 相邻兄弟选择器:选择紧接在另一元素后的元素,且二者有相同父元素,如h1 + p表示选择紧接在 h1 元素之后的所有p元素;

scrapy 中的css使用方法

以a元素来举例说明

  • response.css('a'):返回的是selector对象;
  • response.css('a').extract():返回的是a标签对象;
  • response.css('a::text').extract_first():返回的是第一个a标签中文本的值;
  • response.css('a::attr(href)').extract_first():返回的是第一个a标签中href属性的值;
  • response.css('a[href*=image]::attr(href)').extract():返回所有a标签中href属性包含image的值;
  • response.css('a[href*=image] img::attr(src)').extract():返回所有a标签下image标签的src属性;

yield scrapy.Request(url=next, callback=self.parse) 表示再次创建一个请求,并且该请求的回调函数是 parse 本身,代码运行效果如下所示。
python scrapy 怕学不会?看这篇就可以了。爬虫120例第42例,采集超级产品经理频道
如果想要保存运行结果,运行下面的命令即可。

scrapy crawl pm -o pm.json

python scrapy 怕学不会?看这篇就可以了。爬虫120例第42例,采集超级产品经理频道
如果想要将每条数据存储为单独一行,使用如下命令即可 scrapy crawl pm -o pm.jl 。

python scrapy 怕学不会?看这篇就可以了。爬虫120例第42例,采集超级产品经理频道

生成的文件还支持 csv 、 xml、marchal、pickle ,可自行尝试。

下面将数据管道利用起来
打开 pipelines.py 文件,修改类名 MyProjectPipeline → TitlePipeline,然后编入如下代码:

class TitlePipeline:
    def process_item(self, item, spider):  # 移除标题中的空格
        if item["title"]:
            item["title"] = item["title"].strip()
            return item
        else:
            return DropItem("异常数据")

该代码用于移除标题中的左右空格。

编写完毕,需要在 settings.py 文件中开启 ITEM_PIPELINES 配置。

ITEM_PIPELINES = {
   'my_project.pipelines.TitlePipeline': 300,
}

300 是 PIPELINES 运行的优先级顺序,根据需要修改即可。再次运行爬虫代码,会发现标题的左右空格已经被移除。

到此 scrapy 的一个基本爬虫已经编写完毕。

python - 爬虫Scrapy框架之css选择器使用 0

猜你喜欢

转载自blog.csdn.net/m0_51933492/article/details/127820920