安装
安装 Python
-
点击下载的文件安装
-
安装完成后,找到安装后的文件。设置环境变量。给
PATH
添加C:\Users\xxx\AppData\Local\Programs\Python\Python38-32
、C:\Users\xxx\AppData\Local\Programs\Python\Python38-32\Scripts
-
在
cmd
中输入python
和pip
正常显示
安装 Scrapy
直接使用pip install scrapy
安装失败。
这里先手动安装几个依赖库
-
安装
wheel
:pip install wheel
, -
安装
lxml
:到http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml,下载对应版本的文件。下载后在cmd
中输入pip install 文件路劲
安装 -
安装
pyOpenSSL
:到https://pypi.org/project/pyOpenSSL/#files,找到pyOpenSSL-19.1.0-py2.py3-none-any.whl
,点击下载。然后在cmd
中安装pip install 文件路劲
-
安装
Twisted
:到http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted,下载对应版本的文件。下载后在cmd
中安装pip install 文件路劲
-
安装
pywin32
:到https://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/,找到对应版本,点击下载。下载后打开文件安装 -
在
cmd
中输入pip install scrapy
安装 -
在
cmd
中输入scrapy
正常显示
整体架构和组成
Spiders
:爬虫,定义了爬取的逻辑和网页内容的解析规则,主要负责解析响应并生成结果和新的请求Engine
:引擎,处理整个系统的数据流处理,出发事物,框架的核心。Scheduler
:调度器,接受引擎发过来的请求,并将其加入队列中,在引擎再次请求时将请求提供给引擎Downloader
:下载器,下载网页内容,并将下载内容返回给spider
ItemPipeline
:项目管道,负责处理spider
从网页中抽取的数据,主要是负责清洗,验证和向数据库中存储数据Downloader Middlewares
:下载中间件,是处于Scrapy
的Request
和Requesponse
之间的处理模块Spider Middlewares
:spider
中间件,位于引擎和spider
之间的框架,主要处理spider
输入的响应和输出的结果及新的请求middlewares.py
里实现
scrapy
框架的整体执行流程
spider
的yeild
将request
发送给engine
engine
对request
不做任何处理发送给scheduler
scheduler
,生成request
交给engine
engine
拿到request
,通过middleware
发送给downloader
downloader
在获取到response
之后,又经过middleware
发送给engine
engine
获取到response
之后,返回给spider
,spider
的parse()
方法对获取到的response
进行处理,解析出items
或者requests
- 将解析出来的
items
或者requests
发送给engine
engine
获取到items
或者requests
,将items
发送给ItemPipeline
,将requests
发送给scheduler
- **备注:**只有调度器中不存在
request
时,程序才停止,及时请求失败scrapy
也会重新进行请求)
常用命令
scrapy startproject projectname
:创建一个项目名为projectname
的项目scrapy genspider filename xxx.com
:创建一个Spider
爬虫文件scrapy genspider -t crawl filename xxx.com
::创建一个CrawlSpider
爬虫文件scrapy crawl spidername
:运行名为spidername
的爬虫scrapy crawl spidername -o res.json
:运行命名为spidername
的爬虫,并将结果输出到res.json
文件(可以是csv
、xml
、json
格式的文件)scrapy crawl spidername -o res.json -s FEED_EXPORT_ENCODING=UTF8
:运行命名为spidername
的爬虫,并将结果输出到res.json
文件,编码格式为UTF8
scrapy list
:列出所有爬虫scrapy settings [options]
:获取配置信息scrapy shell urlpath
:命令行模式爬取一个页面,方便调试。可以直接用来测试XPath
或CSS
表达式
创建项目
- 执行
scrapy startproject demo
,创建一个名为demo
的项目
项目目录文件介绍
scrapy.cfg
:项目配置文件demo/
:该项目的python
模块。在此放入代码demo/spiders/
:存放Spider
文件,也就是爬虫文件demo/items.py
:相当于一个容器,和字典很像demo/middlewares.py
:中间件demo/pipelines.py
:定义Item Pipeline
的实现,实现数据的清洗,储存,验证demo/settings.py
:全局配置
Spider
基本结构如下:
# -*- coding: utf-8 -*-
import scrapy
class DemoSpider(scrapy.Spider):
name = 'demoSpider'
allowed_domains = ['xxx.com']
start_urls = ['http://xxx.com/list/7']
def parse(self, response):
pass
name
:爬虫的名称,唯一的allowed_domains
:允许爬取的域名,比如一些网站有相关链接,域名就和本网站不同,这些就会忽略start_urls
:是Spider
爬取的网页,定义初始的请求url
,可以多个__init__(self)
:初始化方法,在这里可以自定义一些类的属性,实例化一些只需要实例化一次对象等closed(self, spider)
:关闭前执行的方法,用于销毁一些对象等start_requests(self)
:可用来覆盖start_urls
,自定义爬虫爬取parse(self, response)
:是Spider
的一个方法,在请求start_urls
后,之后的方法,这个方法是对网页的解析,与提取自己想要的东西。response
参数是请求网页后返回的内容,也就是你需要解析的网页
CrawlSpider
基本结构如下:
# -*- coding: utf-8 -*-
import scrapy, re
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class CrawlspiderSpider(CrawlSpider):
name = 'crawlSpider'
allowed_domains = ['xxx.com']
start_urls = ['http://xxx.com/list/7']
rules = (
Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),
)
def parse_item(self, response):
item = {}
#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
#item['name'] = response.xpath('//div[@id="name"]').get()
#item['description'] = response.xpath('//div[@id="description"]').get()
return item
rules
属性由几个Rule
对象构成,而Rule
对象定义了提取链接等操作的规则
Rule
对象的六个属性:
LinkExtractor(…)
:用于提取response
中的链接callback='str'
:回调函数,对提取的链接使用,用于提取数据填充item
cb_kwargs
:传递给回调函数的参数字典follow=True/False
:对提取的链接是否需要跟进process_links
:一个过滤链接的函数process_request
:一个过滤链接Request
的函数
LinkExtractor
参数:
allow='re_str'
:正则表达式字符串,提取response
中符合re
表达式的链接。deny='re_str'
:排除正则表达式匹配的链接restrict_xpaths='xpath_str'
:提取满足xpath
表达式的链接restrict_css='css_str'
:提取满足css
表达式的链接allow_domains='domain_str'
:允许的域名deny_domains='domain_str'
:排除的域名tags='tag'/['tag1','tag2',…]
:提取指定标签下的链接,默认会从a
和area
标签下提取链接attrs=['href','src',…]
:提取满足属性的链接unique=True/False
:链接是否去重process_value
:值处理函数,优先级要大于allow
Selector选择器
Scrapy
框架中已内置了Selector
选择器
xpath()
通过书写xpath
表达式,可使程序返回该表达式所对应的所有节点的selector list
选择器列表,从而筛选我们想要定位的元素。
常用规则
/
:表示选取直接子节点//
:表示选取所有子孙节点.
:选取当前节点..
:选取当前结点的父节点@
:选取属性
# ...
def parse(self, response):
# response.xpath('//title/text()')
# response.xpath('//title/text()').extract()
# response.xpath('//title/text()').extract_first()
# response.xpath('//base/@href').extract()
# response.xpath('//a[contains(@href, "image")]/@href').extract()
# response.xpath('//a[contains(@href, "image")]/img/@src').extract()
links = response.xpath('//a[contains(@href, "image")]')
for index, link in enumerate(links):
args = (index, link.xpath('@href').extract(), link.xpath('img/@src').extract())
print 'Link number %d points to url %s and image %s' % args
css()
根据css
表达式,返回该表达式所对应的所有节点的selector list
选择器列表
# ...
from scrapy import Selector
# ...
def parse(self, response):
sel = Selector(html)
text = sel.css('.cla::text').extract_first()
# .cla 表示选中类名为 cla 的节点
# ::text 表示获取文本
# extract_first() 表示返回第一个元素,也可以写成sel.css('.cla::text')[0]来获取第一个元素(容易报错,不过没有就会报超出最大索引的错误)
# extract() 表示选取所有,是一个列表
# sel.css('.cla::sttr('class')').extract_first() 表示获取class
# sel.css('div[class="cla"]::text') 表示获取指定属性的文本
# response 为请求网页的返回值,可以直接写成:response.css()来解析,提取我们想要的信息
# response.css('title::text')
# response.css('base::attr(href)').extract()
# response.css('a[href*=image]::attr(href)').extract()
# response.css('a[href*=image] img::attr(src)').extract()
re()
根据书写的正则表达式,对数据进行提取,返回Unicode
字符串list
列表
不能构造嵌套式的 .re()
调用
def parse(self, response):
# response.xpath('//a[contains(@href, "image")]/text()').re(r'Name:\s*(.*)')
# response.xpath('//a[contains(@href, "image")]/text()').re_first(r'Name:\s*(.*)')
extract()
序列化节点为Unicode
字符串,并返回list
列表
Settings
常用配置介绍
ROBOTSTXT_OBEY
:是否遵循网站的robots.txt
配置DOWNLOAD_DELAY
:爬虫爬取的间隔延迟,单位s
。爬取间隔太短很容易被封COOKIES_ENABLED
:是否允许cookies
。如果注释掉默认没有开启cookie
、为False
时默认使用setting
里面的cookie
、为True
时会把setting
里面的cookie
关掉,使用自定义cookie
FEED_EXPORT_ENCODING='UTF8'
:编码格式,可以设置为UTF8
DEFAULT_REQUEST_HEADERS
:配置默认的请求头DOWNLOADER_MIDDLEWARES
:配置中间件。键值越小表示优先调用的意思ITEM_PIPELINES
:配置管道。键值越小表示优先级越高
- 在
settings.py
文件中可以配置自定义配置
# ...
MY_COOKIES = 'csrftoken=NfqL5bzS9nIAtSqIzN3pkIJw8LcPgzf5; aa_language=cn; django_language=zh-cn; _gcl_au=1.1.1683754222.158253875'
- 需要引入
py
文件
# ...
from scrapy.utils.project import get_project_settings
settings = get_project_settings()
cookieStr = settings['MY_COOKIES']
Items
item
是保存爬取数据的容器,使用的方法和字典差不多
比如我们要提取的信息有title
、thumb
、content
、views
、likes
、author
- 修改
demo/demo/items.py
文件
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class DemoItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# pass
title = scrapy.Field()
thumb = scrapy.Field()
content = scrapy.Field()
views = scrapy.Field()
likes = scrapy.Field()
author = scrapy.Field()
- 在爬虫文件中使用
# ...
from demo.items import DemoItem
# ...
def parse(self, response):
dl = response.css('.board-wrapper dd')
item = DemoItem()
for dd in dl:
item['title'] = dd.css('.board-name::text').extract_first()
# ...
yield item
发表评论