0
点赞
收藏
分享

微信扫一扫

Python之scrapy框架


1. scrapy

​Scrapy​​是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。

1.1 安装scrapy

pip install scrapy

安装过程出现错误:

building 'twisted.test.raiser' 
extension error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual‐cpp‐build‐tools

解决:

http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted

下载twisted对应版本的whl文件(如我的Twisted‐17.5.0‐cp36‐cp36m‐win_amd64.whl),cp后面是 python版本,amd64代表64位,运行命令:
pip install C:\Users\...\Twisted‐17.5.0‐cp36‐cp36m‐win_amd64.whl
pip install Scrapy

如果报错,需要更新pip直接更新即可

python ‐m pip install ‐‐upgrade pip

win32报错:

pip install pypiwin32

如果还不行,直接使用anaconda

安装后,打开anaconda 
点击environments
点击not installed
输入scrapy
apply
在pycharm中选择anaconda的环境

2. scrapy项目的创建以及运行

  1. 创建​​scrapy​​项目

终端输入:scrapy startproject 项目名称

2.项目组成:
spiders
__init__.py
自定义的爬虫文件.py ‐‐‐》由我们自己创建,是实现爬虫核心功能的文件
__init__.py
items.py ‐‐‐》定义数据结构的地方,是一个继承自scrapy.Item的类
middlewares.py ‐‐‐》中间件 代理
pipelines.py ‐‐‐》管道文件,里面只有一个类,用于处理下载数据的后续处理 默认是300优先级, 值越小优先级越高(1‐1000)
settings.py ‐‐‐》配置文件 比如:是否遵守robots协议,User‐Agent定义等

3.创建爬虫文件:
(1)跳转到spiders文件夹 cd 目录名字/目录名字/spiders
(2)scrapy genspider 爬虫名字 网页的域名

爬虫文件的基本组成:

继承scrapy.Spider类
name = 'baidu' ‐‐‐》 运行爬虫文件时使用的名字
allowed_domains ‐‐‐》 爬虫允许的域名,在爬取的时候,如果不是此域名之下的 url,会被过滤掉 start_urls ‐‐‐》 声明了爬虫的起始地址,可以写多个url,一般是一个
parse(self, response) ‐‐‐》解析数据的回调函数
response.text ‐‐‐》响应的是字符串
response.body ‐‐‐》响应的是二进制文件
response.xpath()‐》xpath方法的返回值类型是selector列表
extract() ‐‐‐》提取的是selector对象的是data
extract_first() ‐‐‐》提取的是selector列表中的第一个数据

运行爬虫文件:
scrapy crawl 爬虫名称
注意:应在spiders文件夹内执行

如果运行提示​​robots协议​​​,可以注释掉​​settings.py​​​中​​ROBOTSTXT_OBEY = True​

2. scrapy工作原理

Python之scrapy框架_开发语言

3. yield

  1. 带有 ​​yield​​ 的函数不再是一个普通函数,而是一个生成器​​generator​​,可用于迭代
  2. ​yield​​​ 是一个类似 ​​return​​ 的关键字,迭代一次遇到​​yield​​时就返回​​yield​​后面(右边)的值。重点是:下一次迭代

时,从上一次迭代遇到的​​yield​​后面的代码(下一行)开始执行

  1. 简要理解:​​yield​​​就是 ​​return​​ 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始

5. 实际使用

多条管道下载、多页数据下载

以某网站(仅学习使用)为例:

创建项目名为:​​dangdang​​​,文件名为:​​dang​

dang.py

import scrapy
from dangdang.items import DangdangItem

class DangSpider(scrapy.Spider):
name = 'dang'
allowed_domains = ['category.dangdang.com']
start_urls = ['http://category.dangdang.com/cp01.01.02.00.00.00.html']

base_url = 'http://category.dangdang.com/pg'
page = 1

def parse(self, response):
# pipelines 下载数据
# items 定义数据结构的
# src = //ul[@id="component_59"]/li//img/@src
# alt = //ul[@id="component_59"]/li//img/@alt
# price = //ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()
# 所有的seletor的对象 都可以再次调用xpath方法

li_list = response.xpath('//ul[@id="component_59"]/li')

for li in li_list:
src = li.xpath('.//img/@data-original').extract_first()
# 第一张图片和其他的图片的标签的属性是不一样的
# 第一张图片的src是可以使用的 其他的图片的地址是data-original
if src:
src = src
else:
src = li.xpath('.//img/@src').extract_first()

name = li.xpath('.//img/@alt').extract_first()
price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()

book = DangdangItem(src=src, name=name, price=price)

# 获取一个book就将book交给pipelines
yield book

if self.page < 100:
self.page = self.page + 1

url = self.base_url + str(self.page) + '-cp01.01.02.00.00.00.html'

# 怎么去调用parse方法
# scrapy.Request就是scrpay的get请求
# url就是请求地址
# callback是你要执行的那个函数 注意不需要加()
yield scrapy.Request(url=url, callback=self.parse)

items.py

import scrapy


class DangdangItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 通俗的说就是你要下载的数据都有什么

# 图片
src = scrapy.Field()
# 名字
name = scrapy.Field()
# 价格
price = scrapy.Field()

pipelines.py

# 如果想使用管道的话 那么就必须在settings中开启管道
class DangdangPipeline:

# 在爬虫文件开始的之前就执行的一个方法
def open_spider(self, spider):
self.fp = open('book.json', 'w', encoding='utf-8')

def process_item(self, item, spider):
# 以下这种模式不推荐 因为每传递过来一个对象 那么就打开一次文件 对文件的操作过于频繁

# # (1) write方法必须要写一个字符串 而不能是其他的对象
# # (2) w模式 会每一个对象都打开一次文件 覆盖之前的内容
# with open('book.json','a',encoding='utf-8')as fp:
# fp.write(str(item))

self.fp.write(str(item))

return item

# 在爬虫文件执行完之后 执行的方法
def close_spider(self, spider):
self.fp.close()


import urllib.request


# 多条管道开启
# (1) 定义管道类
# (2) 在settings中开启管道
# 'scrapy_dangdang_095.pipelines.DangDangDownloadPipeline':301
class DangDangDownloadPipeline:
def process_item(self, item, spider):
url = 'http:' + item.get('src')
filename = './books/' + item.get('name') + '.jpg'

urllib.request.urlretrieve(url=url, filename=filename)

return item

​settings.py​​中开启配置管道:

ITEM_PIPELINES = {
'dangdang.pipelines.DangdangPipeline': 300,
'dangdang.pipelines.DangDangDownloadPipeline': 301
}
ROBOTSTXT_OBEY = True # 看网站是否需要关闭(注释)


举报

相关推荐

0 条评论