Scrapy框架爬取数据

因为对爬虫有着很大的好奇心,所以找了一些资料继续开始了学习之旅。

一、Scrapy框架简介

如果你有跑车,你还会步行吗?这是李刚老师书里的一句话。在这里Scrapy就是跑车,而像Python内置的urllib和re模块则是步行,跑车和步行的确都可以到达目的地,但是我们大多数通常还是会选择跑车,毕竟速度快而且又方便。简单的来讲,Scrapy是一个专业的、高效的爬虫框架,当然像这样的框架也不在少数,它使用了专业的Twisted包来处理网络通信,使用lxml、cssselect包来提取HTML页面的有效信息,与此同时,它还提供了有效的线程管理。也就是说,我们可以很方便的使用它来创建一个爬虫。

二、爬取网络数据

2.1爬取单个网页数据

1、创建一个scrapy项目,在该项目文件夹下回出现下面的内容。

scrapy startproject SpiderData

2、在真正的进行爬取数据之前,我们可以先用shell调试工具来看一下我们要爬取的网址是否存在不允许我们进行爬取数据的机制。

scrapy shell https://www.zhipin.com/c100010000-p120106/

响应的状态码为403,说明这个网页开启了反爬虫的一些机制,为了让我们可以对其进行数据的爬取,那么我们就需要进行一下伪装,也就是要设置一下我们请求数据中User-Agent里面的内容。因为我使用的是火狐浏览器,我就以火狐浏览器为例:

scrapy shell -s USER_AGENT='Mozilla/5.0' https://www.zhipin.com/c100010000-p120106/

现在状态码为200,说明没有问题了,可以进行数据的爬取。
3、使用XPath表达式或CSS选择器来提取我们想要爬取的信息。

这里补充一下,XPath语言是一种专门为了抽取HTML文档中的元素、属性和文本等信息而设计的语言,它要比正则表达式更适合处理HTML文档。更多的内容可以通过网络或一些书籍进行系统的学习。


不过仍然遇到了一个问题,使用view(response)命令来查看页面时,却出现了下面的情况:

response获取到的页面也一直是它,所以在scrapy shell中使用XPath一直返回的是空。因为不太清楚的缘故,所以我就只能在换个网址试了一下,这一次就没有什么问题了。

scrapy shell -s USER_AGENT='Mozilla/5.0' https://movie.douban.com/top250?start=

4、调试好之后,那么我们就可以在Scrapy项目中编写爬虫程序了。
items.py:

import scrapy

class SpiderdataItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    #电影名称
    movieName=scrapy.Field()
    #影片链接
    movieLink=scrapy.Field()
    #豆瓣评分
    score=scrapy.Field()

在spiders文件夹中创建一个doubanMovie.py文件。

scrapy genspider doubanMovie "movie.douban.com"

doubanMovie.py:

# -*- coding: utf-8 -*-
import scrapy
from SpiderData.items import SpiderdataItem

class DoubanmovieSpider(scrapy.Spider):
    name = 'doubanMovie'        #爬虫的名字
    allowed_domains = ['movie.douban.com']      #爬虫要爬取网页的域名
    start_urls = ['https://movie.douban.com/top250?start=']   #爬取的首页列表
    
    #该方法主要负责解析数据
    def parse(self, response):
        for movieInfo in response.xpath('//div[@class="item"]'):
            item=SpiderdataItem()
            item['movieName']=movieInfo.xpath('./div[@class="info"]/div/a/span[@class="title"]/text()').extract_first()     #提取电影名字
            item['movieLink']=movieInfo.xpath('./div[@class="pic"]/a/@href').extract_first()
            item['score']=movieInfo.xpath('./div/div[@class="bd"]/div/span[@class="rating_num"]/text()').extract()[0]
            yield item      #使用yield关键字创建一个生成器

pipelines.py:

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html

class SpiderdataPipeline(object):
    def process_item(self, item, spider):
        print("电影名:",item['movieName'],end=' ') #简单输出提取到的代码
        print("电影链接:",item['movieLink'],end=' ')
        print("豆瓣评分:",item['score'])

如下所示,相应的去修改settings.py文件中的信息。
settings.py:

# -*- coding: utf-8 -*-

# Scrapy settings for SpiderData project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     https://docs.scrapy.org/en/latest/topics/settings.html
#     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#     https://docs.scrapy.org/en/latest/topics/spider-middleware.html

BOT_NAME = 'SpiderData'

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


# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'SpiderData (+http://www.yourdomain.com)'

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32

# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
#DOWNLOAD_DELAY = 3
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16

# Disable cookies (enabled by default)
#COOKIES_ENABLED = False

# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False

# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
    #在头部信息中添加用户代理,也就是为了伪装成浏览器
   "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0",

   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
   'Accept-Language': 'en',
}

# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
#    'SpiderData.middlewares.SpiderdataSpiderMiddleware': 543,
#}

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
#    'SpiderData.middlewares.SpiderdataDownloaderMiddleware': 543,
#}

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
#}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    'SpiderData.pipelines.SpiderdataPipeline': 300,
}

# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
#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
# 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

# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = 'httpcache'
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'

5、执行程序。

scrapy crawl doubanMovie

2.2爬取多个网页数据

爬取多个网页和爬取单个网页一样,其实就是利用我们在爬取单个网页过程中所获得的url链接重新在经历一次2.1中的过程,如下所示:
doubanMovie.py:

# -*- coding: utf-8 -*-
import scrapy
from SpiderData.items import SpiderdataItem

class DoubanmovieSpider(scrapy.Spider):
    name = 'doubanMovie'        #爬虫的名字
    allowed_domains = ['movie.douban.com']      #爬虫要爬取网页的域名
    start_urls = ['https://movie.douban.com/top250?start=']   #爬取的首页列表

    count=0;    #记录网页的页数    
    #该方法主要负责解析数据
    def parse(self, response):
        for movieInfo in response.xpath('//div[@class="item"]'):
            item=SpiderdataItem()
            item['movieName']=movieInfo.xpath('./div[@class="info"]/div/a/span[@class="title"]/text()').extract_first()
            item['movieLink']=movieInfo.xpath('./div[@class="pic"]/a/@href').extract_first()
            item['score']=movieInfo.xpath('./div/div[@class="bd"]/div/span[@class="rating_num"]/text()').extract()[0]
            self.length+=1
            yield item

        if self.count<10:
            self.count+=1
            yield scrapy.Request("https://movie.douban.com/top250?start="+str(self.count*25),callback=self.parse)      #创建一个生成器,并指定回调函数,循环采集数据
        

三、一些小方法

1、因为对于我这样的初学者而言,使用scrapy框架还是有一定难度的,所以有时候就需要一些调试功能来找错,所以就需要这个方法了。在使用Scrapy所创建的项目下,创建一个main.py,并将下面的代码复制进去就可以进行调试了。

#-*- coding=utf-8 -*-
#@Time : 2020/7/15 17:57
#@Author : wangjy
#@File : main.py
#@Software : PyCharm
from scrapy.cmdline import execute
import os
import sys

if __name__ == '__main__':
    sys.path.append(os.path.dirname(os.path.abspath(__file__)))
    execute(['scrapy', 'crawl', 'doubanMovie','-s','LOG_FILE=all.log']) #因为我个人比较不喜欢乱糟糟的东西,所以就将debug过程中生成的日志全都输出到all.log文件中去了

2、因为会经常使用的XPath表达式,所以可以使用浏览器中的控制台来先测试一下对错,再移植到代码中可能会好很多。


四、小结

经过了这几天的学习,也算是对爬虫框架Scrapy有了初步的了解,其实上述过程中真正编代码的地方就只有三处:item.py,用于定义自己的数据结构;doubanMovie.py,创建自己的爬虫;pipelines.py,用于接收和处理数据对象item。不过现在还处在知其然而不知其所以然的状态,如生成器,所以还需要后面更为深入的了解。

参考资料:《疯狂Python讲义》《精通Python爬虫框架Scrapy》

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352

推荐阅读更多精彩内容