Scrapy项目实战

一 项目准备工作

1. 创建项目

Scrapy框架常用的命令
创建项目:scrapy startproject xxx
进入项目:cd xxx #进入某个文件夹下
创建爬虫:scrapy genspider xxx(爬虫名) xxx.com (爬取域)
生成文件:scrapy crawl xxx -o xxx.json (生成某种类型的文件)
运行爬虫:scrapy crawl XXX
列出所有爬虫:scrapy list
获得配置信息:scrapy settings [options]

Scrapy项目文件结构

  1. items.py 负责数据模型的建立,类似于实体类
  2. middlewares.py 自己定义的中间件。
  3. pipelines.py 负责对spider返回数据的处理。 (管道文件)
  4. settings.py 负责对整个爬虫的配置。 (项目配置)
    5.spiders目录 负责存放继承自scrapy的爬虫类。(写代码的位置)
  5. scrapy.cfg scrapy基础配置

2 项目配置

设置settings.py 文件,设置相关的配置信息,具体配置见下面参数的说明
配置文件参数说明
(1)ROBOTSTXT_OBEY = True ————— 是否遵守robots.txt规则

说明:

​ robots.txt 是遵循 Robot协议 的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页 不希望 你进行爬取收录。在Scrapy启动后,会在第一时间访问网站的 robots.txt 文件,然后决定该网站的爬取范围。(在某些情况下我们想要获取的内容恰恰是被 robots.txt 所禁止访问的。所以,某些时候,我们就要将此配置项设置为 False ,拒绝遵守 Robot协议 !)
(2)CONCURRENT_REQUESTS = 16-----------开启线程数量,默认16,可以自行设置

​ 这个参数涉及到scrapy爬取的并发量,items的处理速度

(3)DOWNLOAD_DELAY = 3 ——— 下载延迟时间。下载器在下载同一个网站下一个页面前需要等待的时间。该选项可以用来限制爬取速度, 减轻服务器压力。(反爬策略之一)

(4)CONCURRENT_REQUESTS_PER_DOMAIN = 16 将对任何单个域执行的并发(即同时)请求的最大数量。

​ CONCURRENT_REQUESTS_PER_IP = 16 将对任何单个IP执行的并发(即同时)请求的最大数量。如果非零,CONCURRENT_REQUESTS_PER_DOMAIN则忽略该 设置,而改为使用此设置。换句话说,并发限制将应用于每个IP,而不是每个域。

(5)COOKIES_ENABLED = False

​ 是否启用cookie。是否启用cookies middleware。如果关闭,cookies将不会发送给web server。

​ 除非您真的 需要,否则请禁止cookies。在进行通用爬取时cookies并不需要, (搜索引擎则忽略cookies)。禁止cookies能减少CPU使用率及Scrapy爬虫在内存中记录的踪迹,提高性能。

​ COOKIES_DEBUG:默认: False
​ 如果启用,Scrapy将记录所有在request(cookie 请求头)发送的cookies及response接收到的cookies(set-cookie接收头)

(6)AUTOTHROTTLE_START_DELAY = 5

​ 初始下载延迟时间(单位:秒)

(7)AUTOTHROTTLE_MAX_DELAY = 60

​ 高并发请求时最大延迟时间(单位:秒)

(8) USER_AGENT 用户代理

​ 这个是至关重要的,大部分服务器在请求快了会首先检查User_Agent,而scrapy默认的浏览器头是scrapy1.1 我们需要开启并且修改成浏览器头,如:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1。 但是最好是这个USER-AGENT会随机自动更换最好了。
(8)DEFAULT_REQUEST_HEADERS

​ 默认请求头部信息,例如如下配置

DEFAULT_REQUEST_HEADERS = {
    'accept': 'image/webp,*/*;q=0.8',
    'accept-language': 'zh-CN,zh;q=0.8',
    'referer': 'https://www.taobao.com/',
    'user-agent': 'Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36',
}

这个是浏览器请求头,很多网站都会检查客户端的headers,比如豆瓣就是每一个请求都检查headers的user_agent,否则只会返回403,可以开启user-agent

(9) SPIDER_MIDDLEWARES

​ Spider中间件是介入到Scrapy中的spider处理机制的钩子框架,可以插入自定义功能来处理发送给 Spiders 的response,以及spider产生的item和request。

要启用Spider中间件(Spider Middlewares),可以将其加入到 SPIDER_MIDDLEWARES 设置中。 该设置是一个字典,键为中间件的路径,值为中间件的顺序(order)。

(10) DOWNLOADER_MIDDLEWARES

​ 要激活下载器中间件组件,将其加入到 DOWNLOADER_MIDDLEWARES 设置中。 该设置是一个字典(dict),键为中间件类的路径,值为其中间件的顺序(order)。

(11)ITEM_PIPELINES

每个Item Pipeline组件其实就是一个实现了一个简单方法的Python类。他们接受一个item并在上面执行逻辑,还能决定这个item到底是否还要继续往下传输,如果不要了就直接丢弃。

(12)AUTOTHROTTLE — 自动限速 (反爬策略之一)

AUTOTHROTTLE_ENABLED = True  #初始下载延迟
# The initial download delay
AUTOTHROTTLE_START_DELAY = 5   #在高延迟的情况下设置的最大下载延迟
# The maximum download delay to be set in case of high latencies
AUTOTHROTTLE_MAX_DELAY = 60    #Scrapy请求的平均数量应该并行发送每个远程服务器
# The average number of requests Scrapy should be sending in parallel to
# each remote server
AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0    
# Enable showing throttling stats for every response received:
AUTOTHROTTLE_DEBUG = False

(13)是否启用在本地缓存,如果开启会优先读取本地缓存,从而加快爬取速度,视情况而定

HTTPCACHE_ENABLED = True

HTTPCACHE_EXPIRATION_SECS = 0

HTTPCACHE_DIR = ‘httpcache’

HTTPCACHE_IGNORE_HTTP_CODES = []

HTTPCACHE_STORAGE = ‘scrapy.extensions.httpcache.FilesystemCacheStorage’

如何在scrapy中加入日志功能?
答案:在settings.py中加入如下信息

LOG_LEVEL= 'INFO'        #日志级别

LOG_FILE ='log.txt'      #日志打印的文件名称

DEBUG < INFO < WARNING < ERROR

日志案例:(settings.py中设置如下信息)

###############   log settings begin   ######################

LOG_LEVEL = "INFO"

from datetime import datetime
import os

today = datetime.now()

LOG_DIR = "logs"
if not os.path.exists(LOG_DIR):
   os.mkdir(LOG_DIR)

LOG_FILE = "{}/scrapy_{}_{}_{}.log".format(LOG_DIR, today.year, today.month, today.day)

###############   log settings end   ######################

二。案例分析

金10的主页:https://www.jin10.com/
1 创建爬虫项目
使用startproject命令创建项目(金10爬虫项目)

scrapy startproject  jinshi_proj   #使用scrapy产生一个scrapy_name爬虫项目

2 生成创建爬虫脚本
使用genspider命令在项目中创建爬虫脚本

cd   jinshi_proj/jinshi_proj
scrapy genspider jinshi_shuju  "https://www.jin10.com/" 

此时会在jinshi_proj/jinshi_proj/产生一个新的文件jinshi_shuju.py

这个是我们的爬取页面的主入口和页面下载完成后解析主入口。

修改配置文件settings.py:

BOT_NAME = 'jinshi'

SPIDER_MODULES = ['jinshi.spiders']
NEWSPIDER_MODULE = 'jinshi.spiders'

LOG_LEVEL= 'DEBUG'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 32
  1. 数据模型
    分析金10网站,定义数据模型用于保存爬取的数据。

编辑文件jinshi_proj/jinshi_proj/items.py, 内容如下:

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class JinshiItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    #保存日期
    report_time =scrapy.Field()
    # 保存内容
    report_content =scrapy.Field()
  1. spiders中编写爬取逻辑
import scrapy
import time
from jinshi.items import JinshiItem

'''
url,设置需要发起请求的url地址
callback=None,设置请求成功后的回调方法
method='GET',请求方式,默认为get请求
headers=None,设置请求头,字典类型
cookies=None,设置cookies信息,模拟登录用户,字典类型
meta=None,传递参数(字典类型)
encoding='utf-8',设置编码
dont_filter=False, 是否去重,默认为false,表示去重
errback=None, 设置请求失败后的回调
'''
class ShujuSpider(scrapy.Spider):
    name = 'shuju'
    allowed_domains = ['jin10.com']
    # start_urls = ['http://www.jin10.com/']


    def start_requests(self):
        while True:
            yield scrapy.Request('https://www.jin10.com/',dont_filter=True,callback=self.parse)

    def parse(self, response):
        times_list =response.xpath("//div[@class='jin-flash_h']/div[@class='jin-flash_time']/text()").extract()
        content = response.xpath("//div[@class='jin-flash']/div[@id='J_flashList']//div[@class='jin-flash_b']/h4/text()").extract()
        h = time.strftime('%Y-%m-%d')  # 筛选时间段,默认当前时刻
        book =[]
        item = JinshiItem()
        for i,j in zip(times_list,content):
            book.append({"report_time":( h + ' ' + i),"report_content":j})
            item["report_time"] =h + ' ' + i
            item["report_content"] =j
            # print(h + ' ' + i+' '+j)
            yield item

5 运行spider
5.1 数据格式化输出:
(1)保存爬取的内容到json文件中

​ scrapy crawl jinshi_shuju -o jinshi.json

​ 可以查看产生的json文件,将内容拷贝到json在线格式网站

​ https://www.json.cn/, 看数据爬取是否和真实相符。
(2)保存爬取的数据到xml文件中

​ scrapy crawl jinshi_shuju -o jinshi.xml

​ (3)保存爬取的数据到数据报表csv文件中

​ scrapy crawl jinshi_shuju -o jinshi.csv
6. 数据持久化
6.1 保存数据到json文件
​ 使用 Scrapy 提供的 exporter 存储 Json 数据

​ Scrapy 为我们提供了一个 JsonItemExporter 类来进行 Json 数据的存储,非常方便

1 修改上节中的spiders

使用yield改造,使得spider成为一个生成器,不断地往pipeline里面流入待处理的数据

import scrapy
import time
from jinshi.items import JinshiItem

'''
url,设置需要发起请求的url地址
callback=None,设置请求成功后的回调方法
method='GET',请求方式,默认为get请求
headers=None,设置请求头,字典类型
cookies=None,设置cookies信息,模拟登录用户,字典类型
meta=None,传递参数(字典类型)
encoding='utf-8',设置编码
dont_filter=False, 是否去重,默认为false,表示去重
errback=None, 设置请求失败后的回调
'''
class ShujuSpider(scrapy.Spider):
    name = 'shuju'
    allowed_domains = ['jin10.com']
    # start_urls = ['http://www.jin10.com/']


    def start_requests(self):
        while True:
            yield scrapy.Request('https://www.jin10.com/',dont_filter=True,callback=self.parse)

    def parse(self, response):
        times_list =response.xpath("//div[@class='jin-flash_h']/div[@class='jin-flash_time']/text()").extract()
        content = response.xpath("//div[@class='jin-flash']/div[@id='J_flashList']//div[@class='jin-flash_b']/h4/text()").extract()
        h = time.strftime('%Y-%m-%d')  # 筛选时间段,默认当前时刻
        book =[]
        item = JinshiItem()
        for i,j in zip(times_list,content):
            book.append({"report_time":( h + ' ' + i),"report_content":j})
            item["report_time"] =h + ' ' + i
            item["report_content"] =j
            # print(h + ' ' + i+' '+j)
            yield item

2 首先要开启pipeline开关
在settings.py文件中开启ITEM_PIPELINES选项,开启如下信息

ITEM_PIPELINES = {
   'jinshi.pipelines.JinshiPipeline': 300,
}

3 pipelines的逻辑处理

import json

class JinshiPipeline:
    def open_spider(self, spider):
        #新建一个保存文档
        self.file = open('report.txt', 'w+',encoding='utf-8')

    def process_item(self, item, spider):
        #item传过来的数据转成字典保存
        context = json.dumps(dict(item), ensure_ascii=False) + '\n'
        self.file.write(context)
        return item

    def close_spider(self, spider):
        # 关闭
        self.file.close()

小插曲:
新建一个运行start.py

from scrapy.cmdline import execute

# execute('scrapy crawl shuju'.split())
execute('scrapy crawl baidu'.split())
# 正则方法re返回的是unicode列表,无法继续使用selector特性
response.xpath("//input[not(@)]").re(r'.*')
response.xpath("//input[not(@)]").extract()
#Selector 对象和SelectorList对象都有以下几种方法。

#extract() 返回选中内容的Unicode字符串

#re("正则表达式") 正则提取

#extract_first()(SelectorList独有)

#返回列表中的第一个元素内容

#re_first()(SelectorList独有)

#返回列表中的第一个元素内容

参考链接: https://www.cnblogs.com/sunBinary/p/11186596.html

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值