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。不过现在还处在知其然而不知其所以然的状态,如生成器,所以还需要后面更为深入的了解。