scrapy爬取豆瓣电影数据的方法-创新互联
创新互联www.cdcxhl.cn八线动态BGP香港云服务器提供商,新人活动买多久送多久,划算不套路!
小编给大家分享一下scrapy爬取豆瓣电影数据的方法,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨方法吧!
1.建立项目
执行如下命令建立scrapy爬虫项目
scrapy startproject spider_douban
命令执行完成后,建立了spider_douban文件夹,目录结构如下:
.
├── scrapy.cfg
└── spider_douban
├── __init__.py
├── items.py
├── middlewares.py
├── pipelines.py
├── settings.py
└── spiders
├── douban_spider.py
└── __init__.py
2.建立爬虫数据模型
打开 ./spider_douban/items.py 文件,编辑内容如下:
import scrapy class DoubanMovieItem(scrapy.Item): # 排名 ranking = scrapy.Field() # 电影名称 movie_name = scrapy.Field() # 评分 score = scrapy.Field() # 评论人数 score_num = scrapy.Field()
3.新建爬虫文件
新建 ./spiders/douban_spider.py 文件,编辑内容如下:
from scrapy import Request from scrapy.spiders import Spider from spider_douban.items import DoubanMovieItem class DoubanMovieTop250Spider(Spider): name = 'douban_movie_top250' start_urls = { 'https://movie.douban.com/top250' } ''' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36', } def start_requests(self): url = 'https://movie.douban.com/top250' yield Request(url, headers=self.headers) ''' def parse(self, response): item = DoubanMovieItem() movies = response.xpath('//ol[@class="grid_view"]/li') print(movies) print('=============================================') for movie in movies: item['ranking'] = movie.xpath( './/div[@class="pic"]/em/text()').extract()[0] item['movie_name'] = movie.xpath( './/div[@class="hd"]/a/span[1]/text()').extract()[0] item['score'] = movie.xpath( './/div[@class="star"]/span[@class="rating_num"]/text()' ).extract()[0] item['score_num'] = movie.xpath( './/div[@class="star"]/span/text()').re(r'(\d+)人评价')[0] yield item next_url = response.xpath('//span[@class="next"]/a/@href').extract() if next_url: next_url = 'https://movie.douban.com/top250' + next_url[0] yield Request(next_url)
爬虫文件各部分功能记录
douban_spider.py文件主要有几部分构成。
导入模块
from scrapy import Request from scrapy.spiders import Spider from spider_douban.items import DoubanMovieItem
Request类用于请求要爬取的页面数据
Spider类是爬虫的基类
DoubanMovieItem是我们第一步建立的爬取数据模型
初始设置
基于spider类定义的爬虫类DoubanMovieTop250Spider中,首先定义爬虫的基本信息:
name:在项目中爬虫的名称,可以在项目目录中执行scrapy list获取已经定义的爬虫列表
start_urls:是爬取的第一个页面地址
headers:是向web服务器发送页面请求的时候附加的user-agent消息,告诉web服务器是什么类型的浏览器或设备在请求页面,对于不具备简单反爬机制的网站,headers部分可以省略。
为了迷惑web服务器,一般会在爬虫发送web请求的时候定义user-agent信息,这里有两种写法。
header的第一种定义:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36', } def start_requests(self): url = 'https://movie.douban.com/top250' yield Request(url, headers=self.headers)
可以看到,这种写法中,start_urls定义没有了,转而定义了start_requests函数,开始的url写到了函数里。同时,定义了headers字典,在发送Request请求的时候,将headers字典一并发送。这种写法简单直观,缺点是在一个爬虫项目执行期间,所有请求都是一个User-Agent属性。
header的第二种定义:
start_urls = { 'https://movie.douban.com/top250' }
简单、直接的定义start_urls属性,而Request中的header属性通过其他方法另外定义,容后再说。
parse处理函数
逐句分解说明
1.基于我们定义的DoubanMovieItem类创建item实例
item = DoubanMovieItem()
2.解析页面 - 获取内容框架
通过分析页面源码,我们能够看到,页面中的电影信息是保存在了
- 标签中,这个
- 标签中,下面代码获取class属性为grid_view的
- 标签下的所有
- 标签内容。
movies = response.xpath('//ol[@class="grid_view"]/li')
3.解析页面 - 获取分项
在每一个
- 标签中,还有内部结构,通过xpath()解析,将每一项内容解析出来,赋值给item实例中的各个字段。通过查看movie.douban.com/top250页面的源码可以很容易找到这个标签定义的内容。如果我们通过type()函数查看movies的变量类型,可以发现他的类型是
。 - 标签中的每一个
- 标签都是这个列表中的一项,那么就可以对movies做迭代。
首先看看
- 标签中的页面结构:
可以看到要提取数据的各部分所在标签位置:
排名:class属性为pic的
标签下,,标签中...
电影名:class属性为hd的回到代码部分,对之前定义的movies做迭代,逐项获取要抓取的数据。
for movie in movies: item['ranking'] = movie.xpath('.//div[@class="pic"]/em/text()').extract()[0] item['movie_name'] = movie.xpath('.//div[@class="hd"]/a/span[1]/text()').extract()[0] item['score'] = movie.xpath('.//div[@class="star"]/span[@class="rating_num"]/text()').extract()[0] item['score_num'] = movie.xpath('.//div[@class="star"]/span/text()').re(r '(\d+)人评价')[0] yield item
如果到此为止,我们可以将https://movie.douban.com/top250页面中的第一页内容爬取到,但只有25项记录,要爬取全部的250条记录,就要执行下面代码:
next_url = response.xpath('//span[@class="next"]/a/@href').extract() if next_url: next_url = 'https://movie.douban.com/top250' + next_url[0] yield Request(next_url)
USER_AGENT_LIST = [ 'zspider/0.9-dev http://feedback.redkolibri.com/', 'Xaldon_WebSpider/2.0.b1', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)', 'Mozilla/5.0 (compatible; Speedy Spider; http://www.entireweb.com/about/search_tech/speedy_spider/)', 'Speedy Spider (Entireweb; Beta/1.3; http://www.entireweb.com/about/search_tech/speedyspider/)', 'Speedy Spider (Entireweb; Beta/1.2; http://www.entireweb.com/about/search_tech/speedyspider/)', 'Speedy Spider (Entireweb; Beta/1.1; http://www.entireweb.com/about/search_tech/speedyspider/)', 'Speedy Spider (Entireweb; Beta/1.0; http://www.entireweb.com/about/search_tech/speedyspider/)', 'Speedy Spider (Beta/1.0; www.entireweb.com)', 'Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)', 'Speedy Spider (http://www.entireweb.com/about/search_tech/speedyspider/)', 'Speedy Spider (http://www.entireweb.com)', 'Sosospider+(+http://help.soso.com/webspider.htm)', 'sogou spider', 'Nusearch Spider (www.nusearch.com)', 'nuSearch Spider (compatible; MSIE 4.01; Windows NT)', 'lmspider (lmspider@scansoft.com)', 'lmspider lmspider@scansoft.com', 'ldspider (http://code.google.com/p/ldspider/wiki/Robots)', 'iaskspider/2.0(+http://iask.com/help/help_index.html)', 'iaskspider', 'hl_ftien_spider_v1.1', 'hl_ftien_spider', 'FyberSpider (+http://www.fybersearch.com/fyberspider.php)', 'FyberSpider', 'everyfeed-spider/2.0 (http://www.everyfeed.com)', 'envolk[ITS]spider/1.6 (+http://www.envolk.com/envolkspider.html)', 'envolk[ITS]spider/1.6 ( http://www.envolk.com/envolkspider.html)', 'Baiduspider+(+http://www.baidu.com/search/spider_jp.html)', 'Baiduspider+(+http://www.baidu.com/search/spider.htm)', 'BaiDuSpider', 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0) AddSugarSpiderBot www.idealobserver.com', ] DOWNLOADER_MIDDLEWARES = { 'spider_douban.middlewares.RandomUserAgentMiddleware': 400, 'scrapy.contrib.downloadermiddleware.useragent.UserAgentMiddleware': None, }
from spider_douban.settings import USER_AGENT_LIST import random class RandomUserAgentMiddleware(): def process_request(self, request, spider): ua = random.choice(USER_AGENT_LIST) if ua: request.headers.setdefault('User-Agent', ua)
在RandomUserAgentMiddleware()中,每次发送请求数据,会在USER_AGENT_LIST中随机选择一条User-Agent记录。
from scrapy import signals from scrapy.contrib.exporter import CsvItemExporter class SpiderDoubanPipeline(CsvItemExporter): def __init__(self): self.files = {} @classmethod def from_crawler(cls, crawler): print('==========pipeline==========from_crawler==========') pipeline = cls() crawler.signals.connect(pipeline.spider_opened, signals.spider_opened) crawler.signals.connect(pipeline.spider_closed, signals.spider_closed) return pipeline def spider_opened(self, spider): savefile = open('douban_top250_export.csv', 'wb+') self.files[spider] = savefile print('==========pipeline==========spider_opened==========') self.exporter = CsvItemExporter(savefile) self.exporter.start_exporting() def spider_closed(self, spider): print('==========pipeline==========spider_closed==========') self.exporter.finish_exporting() savefile = self.files.pop(spider) savefile.close() def process_item(self, item, spider): print('==========pipeline==========process_item==========') print(type(item)) self.exporter.export_item(item) return item
SpiderDoubanPipeline类是建立项目的时候自行建立的,为了保存文件,做了修改。
def from_crawler(cls, crawler):
在此方法中,定义了一个数据收集器(cls)的实例:‘pipeline’。
connect:链接一个接收器函数(receiver function) 到一个信号(signal)。signal可以是任何对象,虽然Scrapy提供了一些预先定义好的信号。
def spider_opened(self, spider):
CsvItemExporter(savefile):输出 csv 文件格式. 如果添加 fields_to_export 属性, 它会按顺序定义CSV的列名.
def spider_closed(self, spider):
def process_item(self, item, spider):
每个item pipeline组件都需要调用该方法,这个方法必须返回一个 Item (或任何继承类)对象, 或是抛出 DropItem 异常,被丢弃的item将不会被之后的pipeline组件所处理。
为了让我们定义的pipeline生效,要在settings.py文件中,打开ITEM_PIPELINES注释:
ITEM_PIPELINES = { 'spider_douban.pipelines.SpiderDoubanPipeline': 300, }
scrapy crawl douban_movie_top250
如果之前pipeline部分代码没有写,也可以用下面的命令,在爬虫执行的时候直接导出数据:
scrapy crawl douban_movie_top250 -o douban.csv
增加-o参数,可以将爬取到的数据保存到douban.csv文件中。。
看完了这篇文章,相信你对scrapy爬取豆瓣电影数据的方法有了一定的了解,想了解更多相关知识,欢迎关注创新互联-成都网站建设公司行业资讯频道,感谢各位的阅读!
文章标题:scrapy爬取豆瓣电影数据的方法-创新互联
链接地址:http://azwzsj.com/article/poigo.html
- 标签都是这个列表中的一项,那么就可以对movies做迭代。
- 标签内容。
- 标签有一个独特的样式表grid_view,而每一个单独的电影信息保存在了