自学内容网 自学内容网

Day:007(2) | Python爬虫:高效数据抓取的编程技术(scrapy框架使用)

Scrapy 数据的提取

        Scrapy有自己的数据提取机制。它们被称为选择器。我们可以通过使用的选择器re、xpath、css提取数据

提示
不用再安装与引入Xpath,BS4

获得选择器

Response对象获取
正常使用 
response.selector.xpath('//span/text()').get()
response.selector.css('span::text').get()
response.selector.re('<span>')
快捷使用
response.xpath('//span/text').get()
response.css('span::text').get()

创建对象 

from scrapy.selector import Selector

 通过text参数 初始化

body = '<html><body><span>good</span></body></html>'
Selector(text=body).xpath('//span/text()').get()

通过response参数 初始化

from scrapy.selector import Selector
from scrapy.http import HtmlResponse
response =HtmlResponse(url='http://example.com',body=body)
Selector(response=response).xpath('//span/text()').get()
'good'
选择器的方法
S.N.方法 & 描述
extract()、getall()它返回一个unicode字符串以及所选数据
extract_first()、get()它返回第一个unicode字符串以及所选数据
re()它返回Unicode字符串列表,当正则表达式被赋予作为参数时提取
xpath()它返回选择器列表,它代表由指定XPath表达式参数选择的节点
css()它返回选择器列表,它代表由指定CSS表达式作为参数所选择的节点

Scrapy Shell的使用

        Scrapy Shell是一个交互式shell,可以在不运行spider项目时,快速调试 scrapy 代码。

提示
一般用于测试xpath或css表达式,查看它们是否能提取想要的数据

注意
当从命令行运行Scrapy Shell时,记住总是用引号括住url,否则
url包含参数(即 & 字符)不起作用。

在Windows上,使用双引号: 

scrapy shell "https://scrapy.org"

Scrapy 保存数据到文件

  • 用Python原生方式保存
with open("movie.txt", 'wb') as f:
    for n, c in zip(movie_name,
movie_core):
        str = n+":"+c+"\n"
        f.write(str.encode())
  • 使用Scrapy内置方式

         scrapy 内置主要有四种:JSON,JSON lines,CSV,XML
          最常用的导出结果格为JSON,命令如下: 

scrapy crawl dmoz -o douban.json -t json 

 参数设置:

  • -o 后面导出文件名
  • -t 后面导出的类型

                可以省略,但要保存的文件名后缀,写清楚类型

注意
将数据解析完,返回数据,才可以用命令保存,代码如下,格
式为dict或item类型

  • return data
  • yield data

Item Pipeline的使用

        当数据在Spider中被收集之后,可以传递到Item Pipeline中统一进行处理。

特点
        每个item pipeline就是一个普通的python类,包含的方法名如下:

  • 方法名
含义是否必须实现
process_item(self,item,spider)用于处理接收到的item
open_spider(self,spider)表示当spider被开启的时候调用这个方法
close_spider(self,spider)当spider关闭时候这个方法被调用

功能 

  • 接收item

        在 process_item 方法中保存

  • 是否要保存数据

        取决于是否编写代码用于保存数据

  • 决定此Item是否进入下一个pipeline
    • return item 数据进入下一个pipeline
    • drop item 抛弃数据

案例代码 

class SaveFilePipeline:

    def open_spider(self,spider):
        self.file = open('douban5.txt','w')

    def process_item(self, item, spider):
        self.file.write(f'name:{item.get("name")} score:{item.get("score")}\n')

    def close_spider(self,spider):
        self.file.close()
from scrapy.exceptions import DropItem

class XSPipeline:
    def open_spider(self,spider):
        self.file =
open('xs.txt','w',encoding='utf-8')
    def process_item(self, item, spider):
        if item.get('title'):
          
self.file.write(item.get('title'))
            self.file.write('\n')
            return item
        else:
            raise DropItem(f"Missing title
in {item}")
    
    def close_spider(self,spider):
        self.file.close()

Scrapy 使用ImagePipeline 保存图片 

        Scrapy提供了一个 ImagePipeline,用来下载图片这条管道,图片管道 ImagesPipeline 提供了方便并具有额外特性的功能,比如:

  • 将所有下载的图片转换成通用的格式(JPG)和模式(RGB)
  • 避免重新下载最近已经下载过的图片
  • 缩略图生成
  • 检测图像的宽/高,确保它们满足最小限制

使用图片管道 

scrapy.pipelines.images.ImagesPipeline

 使用 ImagesPipeline ,典型的工作流程如下所示::

  • 在一个爬虫中,把图片的URL放入 image_urls 组内(image_urls是个列表)
  • URL从爬虫内返回,进入图片管道
  • 当图片对象进入 ImagesPipeline,image_urls 组内的URLs将被Scrapy的调度器和下载器安排下载
  • settings.py文件中配置保存图片路径参数 IMAGES_STORE
  • 开启管道

注意
需要安装pillow4.0.0以上版本
pip install pillow==9.2.0 

问题
报错:twisted.python.failure.Failure OpenSSL.SSL.Error



解决方案
pip uninstall cryptography
pip install cryptography==36.0.2 

Scrapy 自定义ImagePipeline

问题

使用官方默认图片管道,有如下几个问题:

  • 文件名不友好
  • 存储图片URL的参数名称与类型太固定


解决方案
自定义ImagePipeline,扩展

自定义图片管道 

  • 继承 scrapy.pipelines.images import ImagesPipeline
  • 实现 get_media_requests(self, item, info) 方法
    • 发送请求,下载图片
    • 转发文件名
  • 实现 file_path(self,request,response=None,info=None,*,item=None)
    • 修改文件名与保存路径

代码 

import re

class Scrapy05Pipeline:
    def process_item(self, item, spider):
        return item

from scrapy.pipelines.images import ImagesPipeline
from scrapy.http.request import Request

class MyImagePipeline(ImagesPipeline):
    def get_media_requests(self, item,info):
        return Request(item['image_url'])

  def file_path(self, request,response=None, info=None, *, item=None):
        # 处理文件名中的特殊字符
        # name =item.get('name').strip().replace('\r\n\t\t', '').replace('(','').replace(')','').replace('/','_')
        name = re.sub('/','_',re.sub('[\s()]','',item.get('name')))
        return  f'{name}.jpg'

Scrapy 中settings配置的使用 

        Scrapy允许自定义设置所有Scrapy组件的行为,包括核心、扩展、管道和spider本身。

官网-参考配置

设置 — Scrapy 2.5.0 文档 (osgeo.cn)icon-default.png?t=N7T8https://www.osgeo.cn/scrapy/topics/settings.html

配置文档

  • BOT_NAME

        默认: 'scrapybot'
        Scrapy项目实现的bot的名字。用来构造默认 User-Agent,同时也用来log。
        当你使用 startproject 命令创建项目时其也被自动赋值。

  • CONCURRENT_ITEMS

        默认: 100
        Item Processor(即 Item Pipeline) 同时处理(每个response的)item的最大值 

  • CONCURRENT_REQUESTS

        默认: 16
        Scrapy downloader 并发请求(concurrent requests)的最大值。 

  • CONCURRENT_REQUESTS_PER_DOMAIN

        默认: 8
        对单个网站进行并发请求的最大值。 

  • CONCURRENT_REQUESTS_PER_IP

        默认: 0
        对单个IP进行并发请求的最大值。如果非0,则忽略
        CONCURRENT_REQUESTS_PER_DOMAIN 设定, 使用该设定。 也就是说,并发限制将针对IP,而不是网站。
        该设定也影响 DOWNLOAD_DELAY: 如果CONCURRENT_REQUESTS_PER_IP 非0,下载延迟应用在IP而不是网站上。 

  • FEED_EXPORT_ENCODING ='utf-8'

        设置导出时文件的编码 

  • DEFAULT_REQUEST_HEADERS

        默认: 

{
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en',
}

         Scrapy HTTP Request使用的默认header。由
         DefaultHeadersMiddleware 产生。

  • DOWNLOADER_MIDDLEWARES

        默认:: {}
        保存项目中启用的下载中间件及其顺序的字典

  • DOWNLOAD_DELAY

        默认: 0
        下载器在下载同一个网站下一个页面前需要等待的时间。该选项可以用来限制爬取速度, 减轻服务器压力。同时也支持小数 

  • DOWNLOAD_TIMEOUT

        默认: 180
        下载器超时时间(单位: 秒)

  •  ITEM_PIPELINES

        默认: {}
        保存项目中启用的pipeline及其顺序的字典。该字典默认为空,值(value)任意。 不过值(value)习惯设定在0-1000范围内

  • DEPTH_LIMIT

        默认: 0
        类: scrapy.spidermiddlewares.depth.DepthMiddleware
        允许为任何站点爬行的最大深度。如果为零,则不会施加任何限制。

  • LOG_ENABLED

        默认: True
        是否启用logging

  • LOG_ENCODING

        默认: 'utf-8'
        logging使用的编码。

  • LOG_FILE

        默认: None
        logging输出的文件名。如果为None,则使用标准错误输出(standard error)。

  • LOG_FORMAT

        默认: '%(asctime)s [%(name)s] %(levelname)s: %(message)s'
        日志的数据格式

  • LOG_DATEFORMAT

        默认: '%Y-%m-%d %H:%M:%S'
        日志的日期格式

  • LOG_LEVEL

        默认: 'DEBUG'

        log的最低级别。可选的级别有: CRITICAL、 ERROR、WARNING、INFO、DEBUG

  • LOG_STDOUT

        默认: False
        如果为 True ,进程所有的标准输出(及错误)将会被重定向到log中

  • ROBOTSTXT_OBEY

        默认: True
        是否遵循robots协议 

  • USER_AGENT

        默认: "Scrapy/VERSION (+http://scrapy.org/)"
        爬取的默认User-Agent,除非被覆盖

Scrapy默认BASE设置

        scrapy对某些内部组件进行了默认设置,这些组件通常情况下是不能被修改的,但是我们在自定义了某些组件以后,比如我们设置了自定义的middleware中间件,需要按照一定的顺序把他添加到组件之中,这个时候需要参考scrapy的默认设置,因为这个顺序会影响scrapy的执行,下面列出了scrapy的默认基础设置

注意
如果想要修改以下的某些设置,应该避免直接修改下列内容,
而是修改其对应的自定义内容

{
  
'scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware': 100,

'scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware': 300,

'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware': 350,
  
'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': 400,
  
'scrapy.downloadermiddlewares.retry.RetryMiddleware': 500,
  
'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware': 550,
  
'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware': 580,
  
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 590,
  
'scrapy.downloadermiddlewares.redirect.RedirectMiddleware': 600,
  
'scrapy.downloadermiddlewares.cookies.CookiesMiddleware': 700,
  
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 750,

'scrapy.downloadermiddlewares.chunked.ChunkedTransferMiddleware': 830,
  
'scrapy.downloadermiddlewares.stats.DownloaderStats': 850,
  
'scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware': 900,
}


 如果需要关闭下载处理器,为其赋值为 None 即可

提示
有时添加了一些自定义的组件,无法应用到效果,可以从执行
顺序方面入手
执行顺序:输值越小,优先级越高


原文地址:https://blog.csdn.net/m0_49547615/article/details/137697159

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!