一、安装
#1 pip3 install scrapy(mac,linux)
#2 windows上(80%能成功,少部分人成功不了)
1、pip3 install wheel #安装后,便支持通过wheel文件安装软件,wheel文件官网:https://www.lfd.uci.edu/~gohlke/pythonlibs
3、pip3 install lxml
4、pip3 install pyopenssl
5、下载并安装pywin32:https://sourceforge.net/projects/pywin32/files/pywin32/
6、下载twisted的wheel文件:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
7、执行pip3 install 下载目录Twisted-17.9.0-cp36-cp36m-win_amd64.whl
8、pip3 install scrapy
# 3 就有scrapy命令
-D:Python36Scriptsscrapy.exe 用于创建项目
二、框架简介
执行流程图
-
引擎(EGINE)
引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。
(scrapy的核心,用于转发数据或请求,如果是数据,转到管道去保存,如果是请求,转到调度器,如果来的是响应对象,转给爬虫)
-
调度器(SCHEDULER)
用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址(用于处理要爬取的url的顺序,深度优先/表示一条路走到黑,还是广度优先/表示同一层先爬下来,,去重)
-
下载器(DOWLOADER)
用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的(向外要爬取的地址发送请求)
-
爬虫(SPIDERS)
SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求 -
项目管道(ITEM PIPLINES)
在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作(需要在settings中配置)
-
下载器中间件(Downloader Middlewares)
位于Scrapy引擎和下载器之间,主要用来处理从EGINE传到DOWLOADER的请求request,已经从DOWNLOADER传到EGINE的响应response,你可用该中间件做以下几件事
- process a request just before it is sent to the Downloader (i.e. right before Scrapy sends the request to the website);
- change received response before passing it to a spider;
- send a new Request instead of passing received response to a spider;
- pass response to a spider without fetching a web page;
- silently drop some requests.
-
爬虫中间件(Spider Middlewares)
位于EGINE和SPIDERS之间,主要工作是处理SPIDERS的输入(即responses)和输出(即requests)
执行顺序:爬虫把要爬的url转发给引擎,引擎再转发给调度器,由调度器决定顺序,返回给引擎,引擎再把要爬取的url通过下载中间件(用于加个头,cookie啥的)向需要爬取的服务端发送请求,响应回来之后也通过下载中间件给引擎,引擎判断是响应数据之后,转发给爬虫,爬虫对数据进行处理,返回一个新的需要爬的地址(就继续上面的流程)或者需要保存的数据,数据部分由引擎转发给管道,保存数据
目录介绍
firstscrapy # 项目名字
firstscrapy # 包
-spiders # 所有的爬虫文件放在里面
-baidu.py # 一个个的爬虫(以后基本上都在这写东西)
-chouti.py
-middlewares.py # 中间件(爬虫,下载中间件都写在这)
-pipelines.py # 持久化相关写在这(items.py中类的对象)
-main.py # 自己加的,执行爬虫
-items.py # 一个一个的类,
-settings.py # 配置文件
scrapy.cfg # 上线相关
settings参数介绍
1 默认情况,scrapy会去遵循爬虫协议
2 修改配置文件参数,强行爬取,不遵循协议
-ROBOTSTXT_OBEY = False
3 USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
4 LOG_LEVEL='ERROR' # 运行的时候就不会把其他日志展示出来
三、基本使用
1 基本命令
# 创建项目
scrapy startproject firstscrapy
# 创建爬虫
scrapy genspider 爬虫名 爬虫地址
scrapy genspider chouti dig.chouti.com
# 一执行就会在spider文件夹下创建出一个py文件
# 运行爬虫
scrapy crawl chouti # 带运行日志
scrapy crawl chouti --nolog # 不带日志
# 支持右键执行爬虫
# 在项目路径下新建一个main.py
from scrapy.cmdline import execute
execute(['scrapy','crawl','chouti'])
2 数据解析
#xpath:
-response.xpath('//a[contains(@class,"link-title")]/text()').extract() # 取文本
-response.xpath('//a[contains(@class,"link-title")]/@href').extract() #取属性
#css
-response.css('.link-title::text').extract() # 取文本
-response.css('.link-title::attr(href)').extract_first() # 取属性
3 数据持久化
items.py
# 持久化匹配的字段
class ChoutiItem(scrapy.Item):
# define the fields for your item here like:
title = scrapy.Field()
laiyuan = scrapy.Field()
spiders/chouti.py
import scrapy
class ChoutiSpider(scrapy.Spider):
name = 'chouti'
allowed_domains = ['dig.chouti.com']
start_urls = ['http://dig.chouti.com/']
def parse(self, response):
# 返回要爬取的页面,或者返回要保存的数据
# 下面两者效果相同
from pachong.items import ChoutiItem
item = ChoutiItem()
div_list = response.css('.link-con .link-item')
# div_list = response.xpath('//div[contains(@class,"link-item")]')
for div in div_list:
title = div.css('.link-title::text').extract_first()
laiyuan = div.css('.link-from::text').extract_first()
# title = div.xpath('//a[contains(@class,"link-title")]/text()').extract()
if not laiyuan:
laiyuan = ''
print(title,laiyuan)
item['title'] = title
item['laiyuan'] = laiyuan
yield item
pipelines.py
import pymysql
class PachongPipeline:
def open_spider(self,spider):
self.conn = pymysql.connect(host='127.0.0.1', user='root', password="root",
database='pachong', port=3306)
def process_item(self, item, spider):
cursor = self.conn.cursor()
sql = 'insert into chouti (title,laiyuan)values(%s,%s)'
cursor.execute(sql,[item['title'],item['laiyuan']])
self.conn.commit()
return item
def close_spider(self,spider):
self.conn.close()
settings.py
ITEM_PIPELINES = {
'pachong.pipelines.PachongPipeline': 300,
}
# 配置优先级