语言小结
  • program-language-note
  • contact
  • common
    • 代码风格
    • 概念语法
      • 类型
      • 注释
      • 字符
      • 语句
      • 操作符
      • 函数
        • 递归
    • 格式化参数
    • 源码结构
    • 数据结构
    • 名词
  • 电路
    • 内存地址
    • Untitled
    • Code
  • C
    • note
    • overview
      • helloworld.c
      • c标准
      • 关键字
      • tips
      • util.c
    • 语法
      • 函数
        • main
      • const
      • static
      • 作用域
    • 编译和运行
      • c代码内存模型
      • 预处理
        • include
        • define
    • 头文件
    • 基本数据类型
      • 整型
      • 枚举
      • 浮点型
      • 指针
      • 数组
      • 结构和联合
    • 指针&数组、指针&函数
    • API
    • 存储结构
    • 操作符
      • sizeof
    • typedef
    • 输入输出
    • 格式化参数
    • 左値右値
    • 性能思考
    • volatile
    • 字符串
      • find_char.c
    • 动态分配
      • alloc.h
      • alloc.c
      • alloc_usage.c
    • note
  • cpp
    • 资源
    • note
    • 数据结构
    • 智能指针
    • 编译过程
  • shell
    • usage
    • Untitled
  • Rust
    • overview
  • Lisp
    • Untitled
  • web
    • overview
      • index
      • 软件工具
      • ARIA规范
      • SEO
    • style
    • html
      • 标签、元素
        • 标签快记
        • 联系信息
        • 引用
        • 列表
        • 语言设置
        • meta
      • 页面结构
        • 图片
        • 视频
        • 引用css、js文件
      • 等价字符
      • 链接
        • 邮件
      • 表单
        • note
      • 表格
    • css
      • 字体
      • 布局
        • position
        • float
        • display
        • flexbox
    • js
    • note
  • java
    • note
    • java语言程序设计
    • 设计模式
      • 大话设计模式-吴强-2010
      • 大话设计模式-程杰
      • 设计模式-gof
      • 设计模式解析
      • 原则
      • 单例
    • java程序设计第10版-基础
    • java程序设计第10版-进阶
    • java核心技术第9版-I
    • jar包
    • 安全
    • 反射
  • python
    • note
    • index
    • 个人记忆点
    • 疑惑
    • simple
    • 精通Python爬虫框架scrapy
    • 语法
    • scrapy
      • notice
      • index
  • 汇编
    • Untitled
  • kotlin
    • index
    • note
    • by android
      • note
      • index
  • groovy
    • gradle
Powered by GitBook
On this page
  • 概览
  • 安装
  • 第一个spider(爬虫)

Was this helpful?

  1. python
  2. scrapy

notice

PreviousscrapyNextindex

Last updated 5 years ago

Was this helpful?

学习了教程的first steps。

basic concepts还没开动

概览

Scrapy最开始设计用途是网络抓取(Web scraping),但是可以用来提取API数据(如 内置支持从HTML/XML 选择和提取数据 ,只要使用CSS 选择器和XPath语法。 内置支持生成feed exports为多种格式,包括json,csv,xml;或者保存为FTP,S3,本地fs 更多查看

快速示例

import scrapy

class QuotesSpider(scrapy.Spider):
    # 作为spider的标记,项目内不能重复
    name = "quotes"
    # 起始地址方式1
    start_urls = [
        'http://quotes.toscrape.com/tag/humor/',
    ]
    # 起始地址方式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)

    # 解析方式1,response是TextResponse类型
    def parse(self, response):
            for quote in response.css('div.quote'):
                yield {
                    'text': quote.css('span.text::text').extract_first(),
                    'author': quote.css('small.author::text').extract_first(),
                    'tags': quote.css('div.tags a.tag::text').extract(),
                }

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

            next_page = response.css('li.next a::attr(href)').extract_first()
            if next_page is not None:
                # 请求方法1,Request不支持相对地址,需要urljoin预处理
                next_page = response.urljoin(next_page)
                yield scrapy.Request(next_page, callback=self.parse)

                # 请求方法2,follow支持相对地址,不需要urljoin
                # follow 中第一个参数可以传递selecotr, 而且直接传递a 的时候,会自动提取href  
                yield response.follow(next_page, self.parse)

    # 解析方式2
    def parse(self, response):



    # response对象
    response.url
            .body
            .follow
            .urljoin
    scrapy.Request
scrapy runspider quotes_spider.py -o quotes.json  
# quotes is name
scrapy crawl quotes -o quotes.json

安装

CPython python 3.4及以上(当前3.7) PyPy 5.9开始

# 使用Anaconda或者 Miniconda安装    
conda install -c conda-forge scrapy  
# 使用pip安装  
pip install Scrapy

scrapy纯Python实现,并基于库: lxml , parsel, w3lib, twisted, cryptography, pyOpenSSL

虚拟环境 创建一个python项目的时候,建议使用virtualenv创建一个虚拟环境,这样可以在虚拟环境里安装和卸载依赖,和其他项目独立不冲突。 (virtualenv创建查看索引)

(conda安装之后,自动创建了base的virtualenv--在aconda安装目录的bin下存放activate--并激活进入)

ubuntu上不要使用Python-scrapy包安装,因为此源更新比较慢,如下安装即可:

sudo apt-get install python-dev python-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev
# 如果是python3
sudo apt-get install python3 python3-dev
# 如果在virtualenv
pip install scrapy

最新的版本PyPy在linux测试过,OS X会有问题,win没测过

第一个spider(爬虫)

在scrapy框架中,爬虫其实就是继承了scrapy.Spider的类,你可以定义一些东西:起始请求页,后续请求页面的过滤,以及怎么解析(可以对照上面的快速示例查看)

在获取页面之后,你会得到html, 需要去分析他的selector。

这整一个过程最好的方式是通过scrapy shell,如执行:

scrapy shell 'http://quotes.toscrape.com/page/1/'
# 会输出一些请求的状态,对象; 你可以快速的获取selectorList,如:  
>>> response.css('title')
[<Selector xpath='descendant-or-self::title' data='<title>Quotes to Scrape</title>'>]   
>>> response.css('title').extract()
['<title>Quotes to Scrape</title>']
# 或者直接获取第一个, ::text表示取标签内的内容, extract_first更优雅因为做了判空处理不会报错
>>> response.css('title::text').extract_first()
>>> response.css('title::text')[0].extract()
'Quotes to Scrape'  
# 还可以对获取的selectorList使用正则:
>>> response.css('title::text').re(r'(\w+) to (\w+)')
['Quotes', 'Scrape']

# 同样支持XPath,实际上css在底层也是转化成XPath  
>>> response.xpath('//title')
[<Selector xpath='//title' data='<title>Quotes to Scrape</title>'>]
>>> response.xpath('//title/text()').extract_first()
'Quotes to Scrape'

div.tags a.tag::text 表示类tags的div 下面 类tag的a,css的语法?

对于XPath,除了能够解析结构走向,还能知悉文本内容。所以相对于爬取的目的,更鼓励取使用XPath解析

存储

scrapy crawl quotes -o quotes.json

历史原因,输出文档是以append而不是覆盖的形式添加到指定文件。所以json格式重复输出可能导致问题,而jl格式不会。

更多

# 解析作者详情并输出
import scrapy


class AuthorSpider(scrapy.Spider):
    name = 'author'

    start_urls = ['http://quotes.toscrape.com/']

    def parse(self, response):
        # follow links to author pages
        for href in response.css('.author + a::attr(href)'):
            yield response.follow(href, self.parse_author)

        # follow pagination links
        for href in response.css('li.next a::attr(href)'):
            yield response.follow(href, self.parse)

    def parse_author(self, response):
        def extract_with_css(query):
            return response.css(query).extract_first().strip()

        yield {
            'name': extract_with_css('h3.author-title::text'),
            'birthdate': extract_with_css('.author-born-date::text'),
            'bio': extract_with_css('.author-description::text'),
        }

对于访问连接,Scrapy默认会去重处理,可以在DUPEFILTER_CLASS中处理

# -a 后面的参数会被spider的 __init__ 方法接收,并变成spider属性
# 可以在spider内部,通过 getattr(self, 'tag', None)方法获取  
scrapy crawl quotes -o quotes-humor.json -a tag=humor
https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html),或者作为常规的网络爬虫
https://docs.scrapy.org/en/latest/intro/overview.html#what-else