scrapy使用流程 及 爬取猫眼电影排行榜 --存入mysql和mongodb

  1. 准备好数据库
#mysql
#创建库:maoyandb,创建表:filmtab
create database maoyandb charset=utf8;
create table filmtab(name varchar(100),star varchar(300),time varchar(50);

#mongodb
#mongodb数据库不需要提前创建库和集合,运行时自动创建
  1. 在shell中创建scrapy项目

scrapy startproject Maoyan

  1. 创建爬虫文件maoyan.py:scrapy genspider 爬虫名 访问的域名(不带www.)

cd Maoyan
scrapy genspiser maoyan maoyan.com

  1. items.py中定义要抓取的数据结构:电影名、主演、上映时间
import scrapy

class MaoyanItem(scrapy.Item)
	'''定义要爬取的数据结构:名称+主演+上映时间'''
	#相当于你定义了一个字典:{'name':'','star':'','time':''}
	name = scrapy.Field()	#Field()的内部实现就是字典
	star = scrapy.Field()
	time = scrapy.Field()
  1. 爬虫文件maoyan.py
import scrapy
from ..items import MaoyanItem	#因为需要将数据通过items.py中定义的变量传给管道pipeline.py保存,所以将items.py中的MaoyanItem这个类导进来

class MaoyanSpider(scrapy.Spider):
	name = 'maoyan'	#爬虫名,可修改
	allowed_domains = ['maoyan.com']	#域名
	#scrapy源码中scrapy.Spider类写的stat_requests()一次只能给到调度器一个url,这样达不到多线程一次性抓取多个url的目的,需要在下面重写
	#start_urls = ['https://maoyan.com/board/4?offset=0']	#电影排行第一页的url

	#重写scrapy框架的scrapy.Spider类的start_requests()方法,不重写的话url地址只能一个个交给调度器进行请求,重写是为了将所有想请求的url一次性给到调度器入队列
	def start_requests(self):
		url = 'https://maoyan.com/board/4?offset={}'	#排行榜url的规律是每页的offset间隔10
		for offset in range(0,91,10):
			page_url = url.format(offset)
			#将需要请求的url交给调度器
			yield scrapy.Request(			
					url=page_url,		#传给调度器的url
					callback=self.parse_html	#指定请求响应回来后解析html对象的函数
					)

	#解析响应的函数
	def parse_html(self,response):
		#实例化items.py中的类:MaoyanItem获取数据结构
		item = MaoyanItem()	
		
		dd_list = response.xpath('//dl[@class="board-wrapper"]/dd')	#xpath表达式自己去写,返回的数据格式为['<selector data='A'>','<selector data='B'>,....]
		
		#将解析出来的数据放到item中
		for dd in dd_list:
			#给Item对象的3个属性赋值,现在这个版本必须使用字典的['']
			#使用get()获取xpath()返回的数据的第一个序列化的元素('字符串'),获取你要的数据
			item['name'] = dd.xpath('./a/@title').get().strip()	
			item['star'] = dd.xpath('.//p[@class="star"']/text()).get().strip()
			item['time'] = dd.xpath('.//p[@class="releasetime"]/text()').get().strip()
			
			#循环一次,将整理好的数据提交给管道一次(这样效率高)
			yield item
  1. 管道文件pipelines.py
import pymysql
from .settings import *	#将settings.py导进来,因为在里面定义了数据库的账号信息变量,这里引用
import pymongo

#数据在终端显示的管道
class MaoyanPipeling(object):
	def process_item(self,item,spider):
		print(item['name'],item['time'],item['star'])
		return item

#数据存入mysql的管道类
class MaoyanMysqlPipeline(object):
	#open_spider方法:监听爬虫,爬虫启动时只执行1次,一般用于数据库连接
	def open_spider(self,spider):
		#连接数据库
		self.db = pymysql.connect(
				host=MYSQL_HOST,
				user=MYSQL_USER,
				password=MYSQL_PWD,
				database=MYSQL_DB,
				charset=MYSQL_CHAR
				)
		self.cursor = self.db.cursor()
		
	def process_item(self,item,spider):
		#sql插入语句:insert into 表名 value(字段1的值,字段2的值...)
		ins = 'insert into filmtab values(%s,%s,%s)'
		L = [item['name'],item['star'],item['time']
		self.cursor.execute(ins,L)
		self.db.commit()
		return item	#将item数据传入下一个要用的数据库,比如mongodb
		
	#close_spider监听爬虫,爬虫结束时只执行1次,一般用于数据库断开
	def close_spider(self,spider):
		self.cursor.close()
		self.db.close()		

#数据存入mongodb
class MaoyanMongoPipeline(object):
	#连数据库
	def open_spider(self,spider):
		self.conn = pymongo.MongoClient(MONGO_HOST,NONG_PORT)
		self.db = self.conn[MONGO_DB]	#库对象
		self.myset = self.db[MONGO_SET]	#集合对象
	def process item(self,item,spider):
		d = dict(item)	#将传进来要存的数据item转为字典,其实item本质就是个字典
		self.myset.inser_one(d)	#将数据插入mongodb数据库
		
		return item	
  1. settings.py
ROBOTSTXT_OBEY = True	#将君子协议置为False

#加上User-Agent
DEFAULT_REQUEST_HEADERS = {
		'Accept':...,
		'Accept-Laguage':..,
		'User-Agent':'xxx'	#去网上找一个
		}

#打开管道
ITEM_PIPELINES = {'Maoyan.pipelines.MaoyanPipeline':300,
		  		  'Maoyan.pipelines.MaoyanMysqlPipeline':200,	#添加的存mysql的管道,数值表示存入的优先级(先存哪个)
		          'Maoyan.pipelines.MaoyanMongoPipeline':249,	#存mongodb的管道
		 		 }

#设置显示的日志类别
LOG_LEVEL = 'WARNING'	#显示严重程度大于等于WARNING警告的日志
#设置日志不显示在终端,单独保存到log文件中
LOG_FILE = 'maoyan.log'

#定义存入mysql相关变量
MYSQL_HOST = '127.0.0.1'
MYSQL_USER = 'root'
MYSQL_PWD = '123456'
MYSQL_DB = 'maoyandb'
MYSQL_CHAR = 'utf8'

#定义mongodb常用变量
MONGO_HOST = '127.0.0.1'	
MONGO_PORT = 27017	#端口
MONGO_DB = 'maoyandb'	#库名
MONGO_SET = 'filmtab'	#集合名

#设置存Json文件时导出的编码,不设置不能显示中文
FEED_EXPORT_ENCODING = 'utf-8'
  1. 在主项目目录下新建r爬虫执行文件:run.py
from scrapy import cmdline

cmdline.execute('scrapy crawl maoyan'.split())
##数据持久化:存csv文件的命令,会保存到项目下
#cmdline.execute('scrapy crawl maoyan -o maoyan.csv'.split())
##数据持久化:存json文件的命令,会保存到项目下
#cmdline.execute('scrapy crawl maoyan -o maoyan.json'.split())
  1. 执行
    执行run.py文件,爬虫项目启动,直接找爬虫文件maoyan.py中的start_requests()执行,这个方法中直接将10个url的地址交给调度器,下载器用多线程同时下载10个html之后response,等10个response回来后找parse_html()解析函数解析(相当于parse_html()调用了10次,每次传入不同的response),解析函数使用的是协程yield,多线程+协程效率绝对高

  2. 额外知识点补充

    1. 日志(严重程度递减) :CRITICAL严重错误,ERROR普通错误,WARNING警告,INFO一般信息,DEBUG调试信息
#在settings.py中可设置显示出来的日志类别
LOG_LEVEL = 'WARNING'	#表示只显示严重程度高于等于WARNING的日志类型
#在settings.py中可设置日志保存成文件,不在终端显示
LOG_FILE = 'maoyan.log'
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值