欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python Scrapy 爬虫 - 爬取多级别的页面

程序员文章站 2022-05-04 11:28:48
...

Python Scrapy 爬虫 - 爬取多级别的页面

互联网中众多的 scrapy 教程模板,都是爬取 下一页\rightarrow下一页形式的,很少有 父级\rightarrow子级 的说明。

本文介绍一些使用 scrapy 爬取三级网页的注意事项。


逐级别传递 item

如何将 item 的信息,从父级传送到子级,是多级别爬取的最重要部分。

Scrapy 用 scrapy.Request 发起请求时,可以带上 meta={'item': item},把之前已收集到的信息传递到新请求里。
在新请求里用 item = response.meta('item') 接受过来,item 就可以继续添加新的收集的信息了。

参考链接:Python Scrapy多层爬取收集数据

注意:meta字段的方法是浅拷贝,并非深拷贝,(可参考官方文档),所以如果 item 有多个字段时,要么在meta中多字段表示,要么使用深拷贝方法。

# 使用 scrapy 在多个 parse 中自上而下逐级传递 item 的方法
# method 1
import copy

yield scrapy.Request(
    url=next_url, 
    meta={
        'item': copy.deepcopy(item_before)
    }, 
    dont_filter=True, 
    callback=self.next_parse
)

# method 2
yield scrapy.Request(
    url=next_url, 
    meta={
        'thing1': thing1_before,
        'thing2': thing2_before
    }, 
    dont_filter=True, 
    callback=self.next_parse
)

是否需要进行 url去重操作?

如果二级页面的 url 是根据某内容来定义 url路径 的,因此会存在很多重复的 二级url,需要不去重操作。

去重机制:scrapy.Request() 的参数 dont_filter 默认是 False(去重)。
每 yield 一个 scrapy.Request(),就将 url参数 与调度器内已有的 url 进行比较,如果存在相同 url 则默认不入队列,如果没有相同的 url 则入队列,
如果想要实现不去重效果,需要将 dont_filter 改为 True

来自参考链接:spider爬取多级url

scrapy selector 的 extract 与 extract_first 方法

  • extract 以列表形式(记此列表为a)返回选择器中的 data 字段,
    extract_first 则返回上述列表a中的第一个元素(多为字符串)
  • 通常 extract 得到的列表中,只有一个元素,所以往往用 extract_first 即可。
    但若 extract 得到的列表中有多个元素,则需要使用 ''.join(a) 得到具体的字符串信息。
  • ' xxx '.strip() 可以用于去掉头尾空白字符

编写 pipeline 注意事项

  • 首先需要在设置中启动pipeline,才可以有效果
  • mkdir创建单级目录,makedirs创建多级目录
  • 需要首先dict(item)
  • 打开文件时
    • w 只可以写文件
    • w+ 可读可写,打开后立即清空
    • r 只可以读文件
    • r+ 可读可写
    • encoding 保存中文必选
  • 写json时,注意使用"而非'
  • json.dump(text, f, ensure_ascii=False, indent=4)可保存中文,并格式化json

启用 scrapy 日志功能

详细见参考链接

Scrapy logging settings