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