Scrapy安装与创建项目

Scrapy爬取静态页面数据

Posted by Yezhiwei on June 4, 2018

Scrapy 安装

pip install scrapy 

以上会报超时错误,所以增加了国内镜像,如下

pip install --index https://pypi.mirrors.ustc.edu.cn/simple/ scrapy

还是会有超时现象,不过重新试一次就自动地把所有相关的包安装成功,最后终端显示如下提示,说明安装成功:

Installing collected packages: cssselect, w3lib, lxml, constantly, incremental, attrs, Automat, hyperlink, Twisted, PyDispatcher, queuelib, pyasn1-modules, service-identity, parsel, scrapy
Successfully installed Automat-0.6.0 PyDispatcher-2.0.5 Twisted-17.5.0 attrs-17.2.0 constantly-15.1.0 cssselect-1.0.1 hyperlink-17.3.0 incremental-17.5.0 lxml-3.8.0 parsel-1.2.0 pyasn1-modules-0.0.11 queuelib-1.4.2 scrapy-1.4.0 service-identity-17.0.0 w3lib-1.18.0

安装的过程中遇到了一些问题,不过从网上都能找到解决方案

使用 startproject 命令创建项目

mkdir -P /data/bigdata/crawler 为项目目录

scrapy startproject blog 

root@ubuntu238:/data/bigdata/crawler# scrapy startproject blog
Traceback (most recent call last):
  File "/usr/local/bin/scrapy", line 7, in <module>
    from scrapy.cmdline import execute
  File "/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py", line 9, in <module>
    from scrapy.crawler import CrawlerProcess
  File "/usr/local/lib/python2.7/dist-packages/scrapy/crawler.py", line 7, in <module>
    from twisted.internet import reactor, defer
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/reactor.py", line 38, in <module>
    from twisted.internet import default
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/default.py", line 56, in <module>
    install = _getInstallFunction(platform)
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/default.py", line 44, in _getInstallFunction
    from twisted.internet.epollreactor import install
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/epollreactor.py", line 24, in <module>
    from twisted.internet import posixbase
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 18, in <module>
    from twisted.internet import error, udp, tcp
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 28, in <module>
    from twisted.internet._newtls import (
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/_newtls.py", line 21, in <module>
    from twisted.protocols.tls import TLSMemoryBIOFactory, TLSMemoryBIOProtocol
  File "/usr/local/lib/python2.7/dist-packages/twisted/protocols/tls.py", line 63, in <module>
    from twisted.internet._sslverify import _setAcceptableProtocols
  File "/usr/local/lib/python2.7/dist-packages/twisted/internet/_sslverify.py", line 38, in <module>
    TLSVersion.TLSv1_1: SSL.OP_NO_TLSv1_1,
AttributeError: 'module' object has no attribute ‘OP_NO_TLSv1_1'

解决方案为:降低Twisted的版本
pip install Twisted==16.4.1(同样需要指定镜像 pip  install --index https://pypi.mirrors.ustc.edu.cn/simple/ Twisted==16.4.1)

如下提示,说明安装成功
Successfully built Twisted
Installing collected packages: Twisted
  Found existing installation: Twisted 17.5.0
    Uninstalling Twisted-17.5.0:
      Successfully uninstalled Twisted-17.5.0
Successfully installed Twisted-16.4.1

再次执行scrapy startproject blog 创建项目

root@ubuntu238:/data/bigdata/crawler# scrapy startproject blog
New Scrapy project 'blog', using template directory '/usr/local/lib/python2.7/dist-packages/scrapy/templates/project', created in:
    /data/bigdata/crawler/blog

You can start your first spider with:
    cd blog
    scrapy genspider example example.com
    

用tree命令查看项目结构

root@ubuntu238:/data/bigdata/crawler# tree
.
└── blog
    ├── blog
    │   ├── __init__.py
    │   ├── items.py
    │   ├── middlewares.py
    │   ├── pipelines.py
    │   ├── settings.py
    │   └── spiders
    │       └── __init__.py
    └── scrapy.cfg
    
如果提示未安装,需要先安装tree命令,ubuntu安装如:apt-get install tree (MacOS brew install tree)    

使用命令 genspider 创建 Spider

scrapy genspider [-t template] <name> <domain>

在当前项目中创建 Spider。
这仅仅是创建 Spider 的一种快捷方法。该方法可以使用提前定义好的模板来生成 Spider。
name 为 Spider 的名字,必须唯一; domain  allowed_domains 的域名
在 spiders 目录下生成爬取数据的类,下面是爬取自己网站的代码(静态网站)

# spiders/blog.py

# -*- coding: utf-8 -*-
import scrapy
from EastmoneySpider.items import DemoItem


class BlogSpider(scrapy.Spider):
    name = 'blog'
    allowed_domains = ['yezhwi.github.io']
    start_urls = ['https://yezhwi.github.io']

    def parse(self, response):
        for sel in response.xpath('//div[@class="post-preview"]'):
            item = DemoItem()
            # extract()返回的也是一个列表
            # item['title'] = sel.xpath('.//h2/text()').extract()
            # extract_first()可以直接返回第一个值,extract_first()有一个参数default,如:extract_first(default="")表示如果匹配不到返回一个空
            item['title'] = sel.xpath('.//h2/text()').extract_first("").strip()
            item['link'] = response.url + sel.xpath('.//a/@href').extract_first("")
            yield item
            
            
name: 用于区别 Spider。 该名字必须是唯一的,您不可以为不同的 Spider 设定相同的名字。
start_urls: 包含了 Spider 在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
parse() 是 Spider 的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。

执行命令进行爬取

scrapy crawl blog 

在这个过程中:

Scrapy 为 Spider 的 start_urls 属性中的每个 URL 创建了 scrapy.Request 对象,并将 parse 方法作为回调函数(callback)赋值给了 Request。

Request 对象经过调度,执行生成 scrapy.http.Response 对象并送回给 spider parse() 方法。

通过选择器提取数据

Selectors 选择器简介:

Scrapy 提取数据有自己的一套机制。它们被称作选择器(seletors),因为他们通过特定的 XPath 或者 CSS 表达式来“选择” HTML 文件中的某个部分。

XPath 是一门用来在 XML 文件中选择节点的语言,也可以用在 HTML 上。

CSS 是一门将 HTML 文档样式化的语言。选择器由它定义,并与特定的 HTML 元素的样式相关连。

XPath 表达式的例子和含义:

/html/head/title: 选择HTML文档中 <head> 标签内的 <title> 元素
/html/head/title/text(): 选择上面提到的 <title> 元素的文字
//td: 选择所有的 <td> 元素
//div[@class="mine"]: 选择所有具有 class="mine" 属性的 div 元素

提取数据:

观察 HTML 源码并确定合适的 XPath 表达式。

在查看了网页的源码后,您会发现网站的信息是被包含在第二个元素中。

可以通过这段代码选择该页面中网站列表里所有元素:

response.xpath('//ul/li')

保存数据到 items.json 文件中

scrapy crawl blog -o items.json