scrapy mysql 豆瓣_Python爬虫之Scrapy+Mysql+Mongodb爬豆瓣top250电影
学习python时,爬虫是一种简单上手的方式,应该也是一个必经阶段。本项目用Scrapy框架实现了抓取豆瓣top250电影,并将图片及其它信息保存下来。爬取豆瓣top250电影不需要登录、没有JS解析、而且只有10页内容,用来练手,太合适不过了。
我的开发环境
WIN10 64位系统
Python 3.6.1
PyCharm、Sublime Text
Mysql、MongoDB,可视化:DbVisualizer、Robomongo
项目目录
项目目录
spiders/sp_douban.py:处理链接,解析item部分
items.py:豆瓣top250电影字段
middlewares.py、user_agents.py:从维护的UserAgent池中随机选取
settings.py:配置文件
main.py:免去在命令行输入运行指令
页面抓取内容分析
内容区
span内容
如图所示,抓取信息对应如下:
class DoubanTopMoviesItem(scrapy.Item):
title_ch = scrapy.Field() # 中文标题
# title_en = scrapy.Field() # 外文名字
# title_ht = scrapy.Field() # 港台名字
# detail = scrapy.Field() # 导演主演等信息
rating_num = scrapy.Field() # 分值
rating_count = scrapy.Field() # 评论人数
# quote = scrapy.Field() # 短评
image_urls = scrapy.Field() # 封面图片地址
topid = scrapy.Field() # 排名序号
用xpath取出对应路径,进行必要的清洗,去除空格等多余内容:
item['title_ch'] = response.xpath('//div[@class="hd"]//span[@class="title"][1]/text()').extract()
en_list = response.xpath('//div[@class="hd"]//span[@class="title"][2]/text()').extract()
item['title_en'] = [en.replace('\xa0/\xa0','').replace(' ','') for en in en_list]
ht_list = response.xpath('//div[@class="hd"]//span[@class="other"]/text()').extract()
item['title_ht'] = [ht.replace('\xa0/\xa0','').replace(' ','') for ht in ht_list]
detail_list = response.xpath('//div[@class="bd"]/p[1]/text()').extract()
item['detail'] = [detail.replace(' ', '').replace('\xa0', '').replace('\n', '') for detail in detail_list]
# 注意:有的电影没有quote!!!!!!!!!!
item['quote'] = response.xpath('//span[@class="inq"]/text()').extract()
item['rating_num'] = response.xpath('//div[@class="star"]/span[2]/text()').extract()
# 评价数格式:“XXX人评价”。用正则表达式只需取出XXX数字
count_list = response.xpath('//div[@class="star"]/span[4]/text()').extract()
item['rating_count'] = [re.findall('\d+',count)[0] for count in count_list]
item['image_urls'] = response.xpath('//div[@class="pic"]/a/img/@src').extract()
item['topid'] = response.xpath('//div[@class="pic"]/em/text()').extract()
爬取链接的三种方式
重写start_requests方法
base_url = "https://movie.douban.com/top250"
# 共有10页,格式固定。重写start_requests方法,等价于start_urls及翻页
def start_requests(self):
for i in range(0, 226, 25):
url = self.base_url + "?start=%d&filter=" % i
yield scrapy.Request(url, callback=self.parse)
初始start_urls加当前页的下一页
base_url = "https://movie.douban.com/top250"
start_urls = [base_url]
# 取下一页链接,继续爬取
new_url = response.xpath('//link[@rel="next"]/@href').extract_first()
if new_url:
next_url = self.base_url+new_url
yield scrapy.Request(next_url, callback=self.parse)
初始start_urls加LinkExtractor 链接提取器方法
# 这个方法需要较大调整(引入更多模块、类继承CrawlSpider、方法命名不能是parse)
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
base_url = "https://movie.douban.com/top250"
start_urls = [base_url]
rules = [Rule(LinkExtractor(allow=(r'https://movie.douban.com/top250\?start=\d+.*')),
callback='parse_item', follow=True)
]
下载及保存内容
综合其他人的教程,本项目集成了多种保存方法,包括保存电影封面至本地、存入MYSQL、存入MONGODB。在settings里配置了ITEM_PIPELINES,用到那种方式,就把注释去掉即可。
自定义下载图片方法
图片效果
# 自定义方法下载图片
class FirsttestPipeline(object):
# 电影封面命名:序号加电影名
def _createmovieImageName(self, item):
lengh = len(item['topid'])
return [item['topid'][i] + "-" + item['title_ch'][i] + ".jpg" for i in range(lengh)]
# 另一种命名法,取图片链接中名字
# def _createImagenameByURL(self, image_url):
# file_name = image_url.split('/')[-1]
# return file_name
def process_item(self, item, spider):
namelist = self._createmovieImageName(item)
dir_path = '%s/%s' % (settings.IMAGES_STORE, spider.name)
# print('dir_path', dir_path)
if not os.path.exists(dir_path):
os.makedirs(dir_path)
for i in range(len(namelist)):
image_url = item['image_urls'][i]
file_name = namelist[i]
file_path = '%s/%s' % (dir_path, file_name)
if os.path.exists(file_path):
print("重复,跳过:" + image_url)
continue
with open(file_path, 'wb') as file_writer:
print("正在下载:"+image_url)
conn = urllib.request.urlopen(image_url)
file_writer.write(conn.read())
file_writer.close()
return item
保存内容至MYSQL数据库
前提是装好mysql,这部分请自行解决。本项目建表语句:
CREATE TABLE DOUBANTOPMOVIE (
topid int(3) PRIMARY KEY ,
title_ch VARCHAR(50) ,
rating_num FLOAT(1),
rating_count INT(9),
quote VARCHAR(100),
createdTime TIMESTAMP(6) not NULL DEFAULT CURRENT_TIMESTAMP(6),
updatedTime TIMESTAMP(6) not NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
具体实现方法:
# 保存内容至MYSQL数据库
class DoubanmoviePipeline(object):
def __init__(self, dbpool):
self.dbpool = dbpool
@classmethod
def from_settings(cls, settings):
dbparams = dict(
host=settings['MYSQL_HOST'],
port=settings['MYSQL_PORT'],
db=settings['MYSQL_DBNAME'],
user=settings['MYSQL_USER'],
passwd=settings['MYSQL_PASSWD'],
charset=settings['MYSQL_CHARSET'],
cursorclass=MySQLdb.cursors.DictCursor,
use_unicode=False,
)
dbpool = adbapi.ConnectionPool('MySQLdb', **dbparams) # **表示将字典扩展为关键字参数
return cls(dbpool)
# pipeline默认调用
def process_item(self, item, spider):
# 调用插入的方法
query=self.dbpool.runInteraction(self._conditional_insert,item)
# 调用异常处理方法
query.addErrback(self._handle_error,item,spider)
return item
def _conditional_insert(self, tx, item):
sql = "insert into doubantopmovie(topid,title_ch,rating_num,rating_count) values(%s,%s,%s,%s)"
lengh = len(item['topid'])
for i in range(lengh):
params = (item["topid"][i], item["title_ch"][i], item["rating_num"][i], item["rating_count"][i])
tx.execute(sql, params)
def _handle_error(self, e):
print(e)
保存内容至MONGODB数据库
前提是装好mongodb,这部分请自行解决。可视化工具推荐Robomongo,本项目保存结果及实现方法:
mongodb截图
# 保存内容至MONGODB数据库
class MongoDBPipeline( object):
mongo_uri_no_auth = 'mongodb://localhost:27017/' # 没有账号密码验证
database_name = 'yun'
table_name = 'coll'
client = MongoClient(mongo_uri_no_auth) # 创建了与mongodb的连接
db = client[database_name]
table = db[table_name] # 获取数据库中表的游标
def process_item(self, item, spider):
valid = True
for data in item:
if not data:
valid = False
raise DropItem("Missing {0}!".format(data))
if valid:
self.table.insert(dict(item))
return item
用内置的ImagesPipeline类下载图片
Scrapy自带的ImagesPipeline 实现起来也很简单。不过,比较下来,速度不及自定义的方法,不知是否哪里写的不对。若有高手发现,欢迎指出原因。
from scrapy.contrib.pipeline.images import ImagesPipeline
from scrapy.http import Request
from scrapy.exceptions import DropItem
# 用Scrapy内置的ImagesPipeline类下载图片
class MyImagesPipeline(ImagesPipeline):
def file_path(self, request, response=None, info=None):
image_name = request.url.split('/')[-1]
return 'doubanmovie2/%s' % (image_name)
# 从item获取url,返回request对象给pipeline处理
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
yield Request(image_url)
# pipeline处理request对象,完成下载后,将results传给item_completed
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
# print(image_paths)
if not image_paths:
raise DropItem("Item contains no images")
# item['image_paths'] = image_paths
return item
其它
from scrapy.selector import Selector
Selector(response).xpath('//span/text()').extract()
# 等价于下面写法:
response.selector.xpath('//span/text()').extract() # .selector 是response对象的属性
# 也等价于下面写法(进一步简化):
response.xpath('//span/text()').extract()
完整项目代码见Github
觉得对你有所帮助的话,给个star 吧
scrapy mysql 豆瓣_Python爬虫之Scrapy+Mysql+Mongodb爬豆瓣top250电影相关推荐
- python中scrapy是什么_python爬虫中scrapy组件有哪些?作用是什么?
最近苹果12的消息一直活跃,连小编这种不是果粉的人都知道了.虽然苹果是一部性能不错的手机,但是它各个零件却是来源于不同的地方,可见再好的成品也是需要不同零件支撑的.那么,python爬虫中scrapy ...
- python安装scrapy框架命令_python爬虫中scrapy框架是否安装成功及简单创建
判断框架是否安装成功,在新建的爬虫文件夹下打开盘符中框输入cmd,在命令中输入scrapy,若显示如下图所示,则说明成功安装爬虫框架: 查看当前版本:在刚刚打开的命令框内输入scrapy versio ...
- python爬虫入门练习:BeautifulSoup爬取猫眼电影TOP100排行榜,pandas保存本地excel文件
传送门:[python爬虫入门练习]正则表达式爬取猫眼电影TOP100排行榜,openpyxl保存本地excel文件 对于上文使用的正则表达式匹配网页内容,的确是有些许麻烦,替换出现任何的差错都会导致 ...
- python用scrapy爬虫豆瓣_python爬虫,用Scrapy爬取豆瓣Top250,存入MySQL
小白大四生,虽然是计算机专业,但是对学的几门编程语言缘分不深,然后自学了python.(这是我后来补得,因为我发现我写的太笼统了并不适合给新手看,对不起!所以希望大家轻点喷,后面我会从特别特别特别详细 ...
- pythonscrapy爬虫_Python 爬虫:Scrapy 实例(二)
原标题:Python 爬虫:Scrapy 实例(二) 稍微增加点难度,做个所需项目多一点的,并将的结果以多种形式保存起来.我们就从网络天气预报开始. 首先要做的是确定网络天气数据的来源.打开百度,搜索 ...
- python爬京东联盟_python爬虫框架scrapy实战之爬取京东商城进阶篇
前言 之前的一篇文章已经讲过怎样获取链接,怎样获得参数了,详情请看python爬取京东商城普通篇,本文将详细介绍利用python爬虫框架scrapy如何爬取京东商城,下面话不多说了,来看看详细的介绍吧 ...
- python spider 安装_Python爬虫(11):Scrapy框架的安装和基本使用
大家好,本篇文章我们来看一下强大的Python爬虫框架Scrapy.Scrapy是一个使用简单,功能强大的异步爬虫框架,我们先来看看他的安装. Scrapy的安装 Scrapy的安装是很麻烦的,对于一 ...
- scrapy获取a标签的连接_python爬虫——基于scrapy框架爬取网易新闻内容
python爬虫--基于scrapy框架爬取网易新闻内容 1.需求[前期准备] 2.分析及代码实现(1)获取五大板块详情页url(2)解析每个板块(3)解析每个模块里的标题中详情页信息 点击此处,获取 ...
- python scrapy框架 简书_python爬虫框架——Scrapy架构原理介绍
说起写爬虫,大多数第一时间想到的就是python了.python语法简洁明了,加上及其丰富好用的库,用它来写爬虫有天然的优势. 之前学python的时候也用requests+lxml写过几个爬虫玩,但 ...
最新文章
- 青桔单车 chameleon 跨平台实践
- ERROR 1436 (HY000) at line 1943
- 华为张顺茂:华为工业互联网平台FusionPlant助力国家电网打造泛在电力物联网
- Long-Short Memory Network(LSTM长短期记忆网络)
- java 64位时间戳转换32位时间戳
- CenterOs操作
- 【C++】《C++ Primer Plus》--复习题、编程练习题答案
- Photoshop如何调整证件照背景色
- 成果丰硕!SWORD 斯沃德惊艳亮相“第18届深圳名品家博会”
- win10下硬盘安装(更新)win10
- npm ERR! could not determine executable to run
- [推荐]《人一生要读的60本书》
- OptaPlanner快速开始
- 微服务架构(Microservices)
- Android Framework 电源子系统(04)核心方法updatePowerStateLocked分析-2 循环处理 更新显示设备状态
- 什么是蛋白质结构域?什么是HTH?
- 测试用例的设计方法(七种)详细分析
- MATLAB(完备)之图像.tif到真彩色图像、索引色图像、灰度图像、 真彩色图像RGB、YIQ图像、HSV图像、YCbCr图像转换代码
- 盐城北大青鸟:Java的四大就业方向,薪资也是一级棒
- 逐步回归matlab函数,逐步回归matlab程序