学习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电影相关推荐

  1. python中scrapy是什么_python爬虫中scrapy组件有哪些?作用是什么?

    最近苹果12的消息一直活跃,连小编这种不是果粉的人都知道了.虽然苹果是一部性能不错的手机,但是它各个零件却是来源于不同的地方,可见再好的成品也是需要不同零件支撑的.那么,python爬虫中scrapy ...

  2. python安装scrapy框架命令_python爬虫中scrapy框架是否安装成功及简单创建

    判断框架是否安装成功,在新建的爬虫文件夹下打开盘符中框输入cmd,在命令中输入scrapy,若显示如下图所示,则说明成功安装爬虫框架: 查看当前版本:在刚刚打开的命令框内输入scrapy versio ...

  3. python爬虫入门练习:BeautifulSoup爬取猫眼电影TOP100排行榜,pandas保存本地excel文件

    传送门:[python爬虫入门练习]正则表达式爬取猫眼电影TOP100排行榜,openpyxl保存本地excel文件 对于上文使用的正则表达式匹配网页内容,的确是有些许麻烦,替换出现任何的差错都会导致 ...

  4. python用scrapy爬虫豆瓣_python爬虫,用Scrapy爬取豆瓣Top250,存入MySQL

    小白大四生,虽然是计算机专业,但是对学的几门编程语言缘分不深,然后自学了python.(这是我后来补得,因为我发现我写的太笼统了并不适合给新手看,对不起!所以希望大家轻点喷,后面我会从特别特别特别详细 ...

  5. pythonscrapy爬虫_Python 爬虫:Scrapy 实例(二)

    原标题:Python 爬虫:Scrapy 实例(二) 稍微增加点难度,做个所需项目多一点的,并将的结果以多种形式保存起来.我们就从网络天气预报开始. 首先要做的是确定网络天气数据的来源.打开百度,搜索 ...

  6. python爬京东联盟_python爬虫框架scrapy实战之爬取京东商城进阶篇

    前言 之前的一篇文章已经讲过怎样获取链接,怎样获得参数了,详情请看python爬取京东商城普通篇,本文将详细介绍利用python爬虫框架scrapy如何爬取京东商城,下面话不多说了,来看看详细的介绍吧 ...

  7. python spider 安装_Python爬虫(11):Scrapy框架的安装和基本使用

    大家好,本篇文章我们来看一下强大的Python爬虫框架Scrapy.Scrapy是一个使用简单,功能强大的异步爬虫框架,我们先来看看他的安装. Scrapy的安装 Scrapy的安装是很麻烦的,对于一 ...

  8. scrapy获取a标签的连接_python爬虫——基于scrapy框架爬取网易新闻内容

    python爬虫--基于scrapy框架爬取网易新闻内容 1.需求[前期准备] 2.分析及代码实现(1)获取五大板块详情页url(2)解析每个板块(3)解析每个模块里的标题中详情页信息 点击此处,获取 ...

  9. python scrapy框架 简书_python爬虫框架——Scrapy架构原理介绍

    说起写爬虫,大多数第一时间想到的就是python了.python语法简洁明了,加上及其丰富好用的库,用它来写爬虫有天然的优势. 之前学python的时候也用requests+lxml写过几个爬虫玩,但 ...

最新文章

  1. 青桔单车 chameleon 跨平台实践
  2. ERROR 1436 (HY000) at line 1943
  3. 华为张顺茂:华为工业互联网平台FusionPlant助力国家电网打造泛在电力物联网
  4. Long-Short Memory Network(LSTM长短期记忆网络)
  5. java 64位时间戳转换32位时间戳
  6. CenterOs操作
  7. 【C++】《C++ Primer Plus》--复习题、编程练习题答案
  8. Photoshop如何调整证件照背景色
  9. 成果丰硕!SWORD 斯沃德惊艳亮相“第18届深圳名品家博会”
  10. win10下硬盘安装(更新)win10
  11. npm ERR! could not determine executable to run
  12. [推荐]《人一生要读的60本书》
  13. OptaPlanner快速开始
  14. 微服务架构(Microservices)
  15. Android Framework 电源子系统(04)核心方法updatePowerStateLocked分析-2 循环处理  更新显示设备状态
  16. 什么是蛋白质结构域?什么是HTH?
  17. 测试用例的设计方法(七种)详细分析
  18. MATLAB(完备)之图像.tif到真彩色图像、索引色图像、灰度图像、 真彩色图像RGB、YIQ图像、HSV图像、YCbCr图像转换代码
  19. 盐城北大青鸟:Java的四大就业方向,薪资也是一级棒
  20. 逐步回归matlab函数,逐步回归matlab程序

热门文章

  1. python解椭圆方程的例题_如何用python从3个点求椭圆方程
  2. IBM DB2基础知识学习作业
  3. 关于OneDrive一直显示“正在登陆”的一种可能解决方法
  4. 2048游戏代码java总结_软件工程——Java版2048游戏学习报告
  5. 关于Dlink和ADSL不和谐的解决
  6. 谁是软件测试的利益相关者?如何识别它们?
  7. ES9023音频解码芯片原理及应用简介
  8. poi-tl实现word文档按模板下载
  9. Linux(centos7.9)常用命令大全及基础知识
  10. Mac苹果电脑 安装virtualBox