Scrapy爬虫入门系列4抓取豆瓣Top250电影数据
豆瓣有些电影页面需要登录才能查看。
目录[隐藏] |
创建工程
scrapy startproject doubanmoive
定义Item
# -*- coding: utf-8 -*- # Define here the models for your scraped items
# See documentation in:# http://doc.scrapy.org/en/latest/topics/items.html
from scrapy.itemimport Item, Field class DoubanmoiveItem(Item): # define the fields for your item here like:# name = scrapy.Field() url =Field()#豆瓣链接 name = Field()#电影名 year = Field()#上映年份 score = Field()#分数 vote = Field()#评价人数
编写爬虫(Spider)
在doubanmoive/spiders目录下新建moive_spider.py文件
# -*- coding: utf-8 -*-
from scrapy.selectorimport Selector from scrapy.contrib.spidersimport CrawlSpider,Rule from scrapy.contrib.linkextractors.sgmlimport SgmlLinkExtractor from doubanmoive.itemsimport DoubanmoiveItem class MoiveSpider(CrawlSpider): name="doubanmoive" allowed_domains=["movie.douban.com"] start_urls=["http://movie.douban.com/top250"] rules=[ Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/top250\?start=\d+.*'))), //d+表示数字,至少一个数字, .* 任意数量的不包含换行的字符 Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/subject/\d+')),callback="parse_item"),] def parse_item(self,response): sel=Selector(response) item=DoubanmoiveItem() item['url']= response.url item['name']=sel.xpath('//*[@id="content"]/h1/span[1]/text()').extract() // //*选取所有元素 item['year']=sel.xpath('//*[@id="content"]/h1/span[2]/text()').re(r'\((\d+)\)') //re里的r是什么意思? item['score']=sel.xpath('//*[@id="interest_sectl"]/div/p[1]/strong/text()').extract() item['vote']=sel.xpath('//*[@id="interest_sectl"]/div/p[2]/a/span/text()').re(r'\d+')
return item
代码说明:MoiveSpider继承Scrapy中的CrawlSpider,其中rules稍微复杂一些,定义了URL的抓取规则,符合allow正则表达式的链接都会加入到Scheduler(调度程序)。通过分析豆瓣电影Top250的分页URL
http://movie.douban.com/top250?start=25&filter=&type=可以得到以下规则:
Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/top250\?start=\d+.*'))),
而我们真正要抓取的页面是每一部电影的详细介绍,如《肖申克的救赎》的链接为http://movie.douban.com/subject/1292052/,只有subject后面的数字是变化的,根据正则表达式得到如下代码。
Rule(SgmlLinkExtractor(allow=(r'http://movie.douban.com/subject/\d+')),callback="parse_item"),
我们需要抓取这种类型链接中的内容,于是加入callback属性,将Response交给parse_item函数来处理。
在parse_item函数中的处理逻辑非常简单,根据一定的规则抓取内容赋给item并返回Item Pipeline。获取大部分标签的内容不需要编写复杂的正则表达式,我们可以使用XPath。
我们可以通过Chrome开发者工具(F12)来获取某内容的XPath表达式,具体操作为在需要抓取的内容上点击审查元素,下方就会出现开发者工具,并定位到该元素,在内容上点击右键,选择复制XPath。注意最好多测试几个页面看看表达式是否是一样的

存储数据
爬虫获取到数据以后我们需要将其存储到数据库中,之前我们提到该操作需要靠项目管道(pipeline)来处理,其通常执行的操作为:
- 清洗HTML数据
- 验证解析到的数据(检查项目是否包含必要的字段)
- 检查是否是重复数据(如果重复就删除)
- 将解析到的数据存储到数据库中
由于我们获取的数据格式多种多样,有一些存储在关系型数据库中并不方便,可以考虑使用MongoDB。
MySQL不太方便的一点就是需要将数组类型的数据通过分隔符转换。而MongoDB支持存入List、Dict等多种类型的数据。
pipelines.py代码如下:
# -*- coding: utf-8 -*- # Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html from scrapy import log from twisted.enterpriseimport adbapi from scrapy.httpimport Request import MySQLdb import MySQLdb.cursors class DoubanmoivePipeline(object): def__init__(self): self.dbpool= adbapi.ConnectionPool('MySQLdb', db ='scrapy',user='root', passwd ='pwd', cursorclass = MySQLdb.cursors.DictCursor, charset ='utf8', use_unicode =False) def process_item(self, item, spider): query =self.dbpool.runInteraction(self._conditional_insert, item) query.addErrback(self.handle_error)return item def _conditional_insert(self,tx,item): tx.execute("select * from doubanmoive where m_name= %s",(item['name'][0],)) //可以通过网页的subject数字进行排重。
result=tx.fetchone()#log.msg(result,level=log.DEBUG)#print resultif result: log.msg("Item already stored in db:%s" % item,level=log.DEBUG)else: tx.execute(\ "insert into doubanmoive (m_name,m_year,m_score, url, vote) values (%s,%s,%s,%s,%s)",\ (item['name'][0],item['year'][0],item['score'][0],item['url'],item['vote'])) log.msg("Item stored in db: %s" % item, level=log.DEBUG) def handle_error(self, e): log.err(e)
配置文件
在运行爬虫之前还需要将在settings.py中增加一些配置信息。
# -*- coding: utf-8 -*- # Scrapy settings for doubanmoive project## For simplicity, this file contains only the most important settings by# default. All the other settings are documented here:## http://doc.scrapy.org/en/latest/topics/settings.html# BOT_NAME ='doubanmoive' SPIDER_MODULES =['doubanmoive.spiders'] NEWSPIDER_MODULE ='doubanmoive.spiders' ITEM_PIPELINES={'doubanmoive.pipelines.DoubanmoivePipeline':400,} LOG_LEVEL='DEBUG' DOWNLOAD_DELAY =3 RANDOMIZE_DOWNLOAD_DELAY =True USER_AGENT ='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML,like Gecko) Chrome/19.0.1084.54 Safari/536.5' COOKIES_ENABLED =True
# Crawl responsibly by identifying yourself (and your website) on the user-agent#USER_AGENT = 'doubanmoive (+http://www.yourdomain.com)'
ITEM_PIPELINES中定义了MySQL的 Pipeline文件,后面的数字代表执行的优先级顺序,范围为0~1000。而中间的DOWNLOAD_DELAY等信息是为了防止爬虫被豆瓣禁掉,增加了一些随机延迟,浏览器代理等。
至此,抓取豆瓣电影的爬虫就已经完成了。在命令行中执行scrapy crawl doubanmoive让蜘蛛开始爬行吧!


报错:403
CrawlSpider class callback is None follow defaults to True(item['name'][0],)
print list[0] # 输出列表的第一个元素
艺搜参考
Scrapy爬虫入门系列4抓取豆瓣Top250电影数据的更多相关文章
- 基础爬虫,谁学谁会,用requests、正则表达式爬取豆瓣Top250电影数据!
爬取豆瓣Top250电影的评分.海报.影评等数据! 本项目是爬虫中最基础的,最简单的一例: 后面会有利用爬虫框架来完成更高级.自动化的爬虫程序. 此项目过程是运用requests请求库来获取h ...
- Scrapy爬虫入门系列3 将抓取到的数据存入数据库与验证数据有效性
抓取到的item 会被发送到Item Pipeline进行处理 Item Pipeline常用于 cleansing HTML data validating scraped data (checki ...
- requests爬取豆瓣top250电影信息
''' 1.爬取豆瓣top250电影信息 - 第一页: https://movie.douban.com/top250?start=0&filter= - 第二页: https://movie ...
- Scrapy爬虫入门系列2 示例教程
本来想爬下http://www.alexa.com/topsites/countries/CN 总排名的,但是收费了 只爬了50条数据: response.xpath('//div[@class=&q ...
- 简易数据分析 04 | Web Scraper 初尝--抓取豆瓣高分电影
这是简易数据分析系列的第 4 篇文章. 今天我们开始数据抓取的第一课,完成我们的第一个爬虫.因为是刚刚开始,操作我会讲的非常详细,可能会有些啰嗦,希望各位不要嫌弃啊:) 有人之前可能学过一些爬虫知识, ...
- 抓取豆瓣的电影排行榜TOP100
#!/usr/bin/env python # -*- coding:utf-8 -*- """ 一个简单的Python爬虫, 用于抓取豆瓣电影Top前100的电影的名称 ...
- 爬取豆瓣TOP250电影
自己跟着视频学习的第一个爬虫小程序,里面有许多不太清楚的地方,不如怎么找到具体的电影名字的,那么多级关系,怎么以下就找到的是那个div呢? 诸如此类的,有许多,不过先做起来再说吧,后续再取去弄懂. i ...
- python3下scrapy爬虫(第二卷:初步抓取网页内容之直接抓取网页)
上一卷中介绍了安装过程,现在我们开始使用这个神奇的框架 跟很多博主一样我也先选择一个非常好爬取的网站作为最初案例,那么我先用屌丝必备网站http://www.shaimn.com/xinggan/作为 ...
- python3下scrapy爬虫(第四卷:初步抓取网页内容之抓取网页里的指定数据延展方法)
上卷中我运用创建HtmlXPathSelector 对象进行抓取数据: 现在咱们再试一下其他的方法,先试一下我得最爱XPATH 看下结果: 直接打印出结果了 我现在就正常拼下路径 只求打印结果: 现在 ...
随机推荐
- IOS开发使用委托delegate在不同窗口之间传递数据
IOS开发使用委托delegate在不同窗口之间传递数据是本文要介绍的内容,主要是来讲解如何使用委托delegate在不同窗口之间传递数据,具体内容来看详细内容.在IOS开发里两个UIView窗口之间 ...
- isNaN使用的注意事项
NaN是JavaScript的特殊值,表示 Not a Number 用法: isNaN(numValue); 如果值是 NaN, 那么 isNaN 函数返回 true ,否则返回 false . 注 ...
- java获取桌面路径的方法
FileSystemView fsv = FileSystemView.getFileSystemView(); File com=fsv.getHomeDirectory(); System.out ...
- mysql group_concat函数
函数语法: group_concat( [DISTINCT] 要连接的字段 [Order BY 排序字段 ASC/DESC] [Separator '分隔符'] ) 下面举例说明: select * ...
- 如何使用ninja编译系统编译我们的程序?
使用ninja 配置自己的环境来使用ninja 构建程序 Android使用ninja Windows使用 调试 不使用VS 技巧 问题 Ninja的原意是忍者,忍者神龟的忍者.这里被google拿来 ...
- 一起來玩鳥 Starling Framework(2)效能測試以及Image與Texture
上一篇我們放了一個Quad與TextField在舞台上慢慢轉.眼尖的可能會發現轉起來邊緣有點鋸齒,這可以透過設定Starling的反鋸齒來解決,在Main.as裡,新增了_starling之後,可以加 ...
- python 列表合并
列表合并主要有以下方法: 1.用list的extend方法,L1.extend(L2),该方法将参数L2的全部元素添加到L1的尾部 结果:[1, 2, 3, 4, 5, 1, 20, 30] 2.用切 ...
- git学习——分支
分支 创建分支:git branch 如:git branch testing Git通过HEAD指针知道用户是在哪一个分支上工作. 切换分支用git checkout命令,注意:可以用git sta ...
- seo关键字优化条例
SEO 第一: 标题关键字分析 分析和选择行业热门的关键字,并合理的应用于网站标题内及分布到各栏目页面和内页. 其实个人觉得标题.内容.以及与内容相关性链接必须要足.还有就是出现的层次感,例如: a) ...
- Mysql的Root密码忘记,查看或修改的解决方法(图文介绍)
http://www.jb51.net/article/38473.htm 首先启动命令行 1.在命令行运行:taskkill /f /im mysqld-nt.exe 下面的操作是操作mysql中b ...