使用scrapy爬取豆瓣电影Top250
2018-09-16 本文已影响297人
iLeooooo
第一步:安装scrapy
,详情
第二步:安装mongo
。
第三步:使用scrapy
,爬去目标数据
a. 新建项目
- 在自己想要存放的位置(文件夹),使用下面命令创建项目,项目名称自己随意。
scrapy startproject douban
// 为了更好的区分多个版本python
python2 -m scrapy startproject xxx
python3 -m scrapy startproject xxx
创建项目
- 使用
pycharm
打开刚才创建的douban
项目,修改setting.py
文件中的
ROBOTSTXT_OBEY = False
- 创建爬虫项目,使用下面的命令,或者直接创建文件
scrapy genspider douban_spider movie.douban.com
创建爬虫文件
- 安装
xpath
(chrom浏览器插件)
xpath helper
b. 明确目标
- 目标内容为豆瓣Top250电影数据信息
c. 制作爬虫
- 完善保存爬去数据模型对象(修改
items.py
文件)
照着注释写 - 完善爬虫文件(修改
douban_spider.py
文件)
douban_spider - 运行爬虫文件,使用命令
scrapy crawl douban_spider
在spiders
文件夹下面新建python文件,命名为main.py
from scrapy import cmdline
cmdline.execute('scrapy crawl douban_spider'.split())
# 运行main.py文件
- 此时会报错
HTTP403
,修改items.py
文件,打开USER
# 修改前
USER_AGENT = 'douban (+http://www.yourdomain.com)'
# 修改后
USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
- 可以得到粗略的目标数据,然后进行数据解析
d. 存储内容
- 打开网页,右键点击
检查
- 使用xpath插件(点击 Ctrl + Shift + X 激活 XPath Helper 的控制台)
- 左键选中想要获取的数据,点击一下Shift,xpath中就会出现相应的xpath路径
- 编写爬虫代码,回去网页数据
- 创建douban_item模型,保存数据,爬虫代码如下
# -*- coding: utf-8 -*-
import scrapy
from douban.items import DoubanItem
class DoubanSpiderSpider(scrapy.Spider):
# 这是爬虫名
name = 'douban_spider'
# 允许的域名
allowed_domains = ['movie.douban.com']
# 入口url,扔到调度器里面去
start_urls = ['https://movie.douban.com/top250']
# 默认解析方法
def parse(self, response):
# 定义变量保存电影数据列表
movie_list = response.xpath("//div[@class='article']//ol[@class='grid_view']/li")
# 循环每一页电影条目
for i_item in movie_list:
# item文件导入
douban_item = DoubanItem()
# 写详细的xpath,进行数据的解析
douban_item['serial_number'] = i_item.xpath(".//div[@class='item']//em/text()").extract_first()
douban_item['movie_name'] = i_item.xpath(".//div[@class='info']/div[@class='hd']/a/span[1]/text()").extract_first()
content = i_item.xpath(".//div[@class='info']//div[@class='bd']/p[1]/text()").extract()
# 数据的处理
for i_content in content:
content_s = "".join(i_content.split())
douban_item['introduce'] = content_s
douban_item['star'] = i_item.xpath(".//span[@class='rating_num']/text()").extract_first()
douban_item['evaluate'] = i_item.xpath(".//div[@class='star']//span[4]/text()").extract_first()
douban_item['describe'] = i_item.xpath(".//p[@class='quote']/span/text()").extract_first()
# 需要将数据yield到pipelines里面,然后进行数据的存储
yield douban_item
# 解析下一页规则,取后一页的xpath
next_link = response.xpath("//span[@class='next']/link/@href").extract()
if next_link:
next_link = next_link[0]
yield scrapy.Request('https://movie.douban.com/top250' + next_link,callback=self.parse)
- 将文件写入
json
或者cvs
文件中,执行命令
# 将数据写入json文件
scrapy crawl douban_spider -o test.json
# 将数据写入cvs文件,注意写入后,文件的编码
scrapy crawl douban_spider -o test.cvs
e. 将数据存入mongoDB中
- 在
settings
文件中定义mongo的基本配置
mongo_host = "127.0.0.1"
mongo_port = 27017
mongo_db_name = "douban"
mongo_db_collection = "douban_movie"
- 在
pipelines.py
文件中写入数据库相关的代码
2.1 导入mongo
相关的包pymongo
2.2 从settings
文件中导入mongo
相关的配置
2.3 添加初始化方法__init__
2.4 初始化mongo
,创建数据库client,创建数据库,集合
2.5 插入数据
2.6 代码如下
import pymongo
from douban.settings import mongo_host,mongo_port,mongo_db_name,mongo_db_collection
class DoubanPipeline(object):
def __init__(self):
host = mongo_host
port = mongo_port
dbname = mongo_db_name
sheetname = mongo_db_collection
client = pymongo.MongoClient(host=host,port=port)
mydb = client[dbname]
self.post = mydb[sheetname]
def process_item(self, item, spider):
data = dict(item)
self.post.insert_one(data)
return item
2.7 运行,发现数据库中并没有插入数据。原因:
在设置中没有开启pipelines
选项
# 打开这三行的注释
ITEM_PIPELINES = {
'douban.pipelines.DoubanPipeline': 300,
}
2.8 运行,数据插入成功
数据插入成功
f. 设置代理
- ip代理中间件
- 在
middleware.py
中编写代理中间件 - 写好代理ip的中间件代码如下:
# 设置代理ip,设置好了之后要在settings里面更改配置
class my_proxy(object):
def progress_request(self, request, spider):
# 代理服务器地址
request.meta['proxt'] = 'https:xxxx'
# 代理用户名和密码
proxy_name_pass = b'user(xxxxx):pass(xxxx)'
# 对用户名密码进行加密,只能加密base类型数据,要在proxy_name_pass前面加b
encode_name_pass = base64.b64encode(proxy_name_pass)
# 注意Basic后面要加一个空格
request.header['Proxy Authorization'] = 'Basic ' + encode_name_pass.decode()
- 在
settings
里面打开代理中间件的配置
# 把DoubanDownloaderMiddleware改成我们自己刚才创建的类
DOWNLOADER_MIDDLEWARES = {
# 'douban.middlewares.DoubanDownloaderMiddleware': 543,
'douban.middlewares.my_proxy': 543,
}
- User Agent代理中间件
- 创建类,编写方法
class my_useragent(object):
def progress_request(self, request, spider):
# user agent 列表
USER_AGENT_LIST = [
'MSIE (MSIE 6.0; X11; Linux; i686) Opera 7.23',
'Opera/9.20 (Macintosh; Intel Mac OS X; U; en)',
'Opera/9.0 (Macintosh; PPC Mac OS X; U; en)',
'iTunes/9.0.3 (Macintosh; U; Intel Mac OS X 10_6_2; en-ca)',
'Mozilla/4.76 [en_jp] (X11; U; SunOS 5.8 sun4u)',
'iTunes/4.2 (Macintosh; U; PPC Mac OS X 10.2)',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0) Gecko/20100101 Firefox/5.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0) Gecko/20100101 Firefox/9.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20120813 Firefox/16.0',
'Mozilla/4.77 [en] (X11; I; IRIX;64 6.5 IP30)',
'Mozilla/4.8 [en] (X11; U; SunOS; 5.7 sun4u)'
]
# 随机生成user agent
agent = random.choice(USER_AGENT_LIST)
request.header['User Agent'] = agent
- 添加
settings
中的配置
# 把DoubanDownloaderMiddleware改成我们自己刚才创建的类
# 后面的数字表示的是优先级,优先级不能相同
DOWNLOADER_MIDDLEWARES = {
# 'douban.middlewares.DoubanDownloaderMiddleware': 543,
'douban.middlewares.my_proxy': 543,
'douban.middlewares.my_useragent': 544,
}
完
慢慢来,一步一个巴掌印~~~