1.1 进阶篇案例一
案例:爬取豆瓣电影 top250( movie.douban.com/top250 )的电影数据,并保存在 MongoDB 中。
案例步骤:
第一步:明确爬虫需要爬取的内容。
我们做爬虫的时候,需要明确需要爬取的内容,豆瓣电影 TOP 250,我们需要抓取每一部电影的名字,电影的描述信息(包括导演、主演、电影类型等等),电影的评分,以及电影中最经典或者脍炙人口的一句话。
例如:肖申克的救赎
电影的名字:肖申克的救赎。
电影信息(导演:弗兰克·德拉邦特;主演:蒂姆·罗宾斯 / 摩根·弗里曼 / 鲍勃·冈顿 / 威廉姆·赛德勒 / 克兰西·布朗 / 更多...;电影类型:剧情 / 犯罪。)
豆瓣电影评分:9.6。
脍炙人口的一句话:希望让人自由。
第二步:创建爬虫项目。
在 dos下切换到目录
D:scrapy_project
新建一个新的爬虫项目:scrapy startproject douban
第三步:创建爬虫。
在 dos下切换到目录。
D:scrapy_projectdoubandoubanspiders
用命令 scrapy genspider doubanmovie "movie.douban.com" 创建爬虫。
第四步: 开始前的准备工作。
(一)、在 scrapy.cfg 同级目录下创建 pycharm 调试脚本 run.py,内容如下:
# -*- coding: utf-8 -*-
from scrapy import cmdline
cmdline.execute("scrapy crawl doubanmovie".split())
(二)、修改 settings 中的 ROBOTSTXT_OBEY = True 参数为 False,因为默认为 True,就是要遵守 robots.txt 的规则, robots.txt 是遵循 Robot协议 的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在 Scrapy 启动后,会在第一时间访问网站的 robots.txt 文件,然后决定该网站的爬取范围。查看 robots.txt 可以直接网址后接 robots.txt 即可。
例如百度:https://www.baidu.com/robots.txt
修改 settings 文件。
(三)、settings.py 里添加 USER_AGENT。
(四)不需要模拟登陆,settings.py 里的 COOKIES_ENABLED ( Cookies中间件) 设置禁用状态。
COOKIES_ENABLED = False
第五步: 定义 Item,编写 items.py 文件。
import scrapy
class DoubanItem(scrapy.Item):
# 电影标题
title = scrapy.Field()
# 电影信息
bd = scrapy.Field()
# 豆瓣评分
star = scrapy.Field()
# 脍炙人口的一句话
quote = scrapy.Field()
第六步: 查看HTML源码,使用XPath helper爬虫插件一起查看需要爬取的字段的 xpath 路径。
# 电影标题
item['title'] = each.xpath(".//span[@class='title'][1]/text()").extract()[0]
# 电影信息
item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]
# 豆瓣评分
item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]
# 脍炙人口的一句话
quote = each.xpath(".//p[@class='quote']/span/text()").extract()
备注:extract()返回的是一个列表,列表里的每个元素是一个对象,extract()把这些对象转换成 Unicode 字符串。
第七步: 分析网站分页的 URL 规律。
第一页的链接地址:
https://movie.douban.com/top250?start=0
第二页的链接地址:
https://movie.douban.com/top250?start=25
最十页的链接地址:
https://movie.douban.com/top250?start=225
通过分析我们得知,每一页的的链接地址 start 的值递增 25,就是下一页的地址。
第八步: 编写爬虫文件。
import scrapy,sys,os
path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(path)
from douban.items import DoubanItem
class DoubamovieSpider(scrapy.Spider):
name = "doubanmovie"
allowed_domains = ["movie.douban.com"]
offset = 0
url = "https://movie.douban.com/top250?start="
start_urls = (
url + str(offset),
)
def parse(self, response):
item = DoubanItem()
movies = response.xpath("//div[@class='info']")
for each in movies:
# 电影标题
item['title'] = each.xpath(".//span[@class='title'][1]/text()").extract()[0]
# 电影信息
item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]
# 豆瓣评分
item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]
# 脍炙人口的一句话
quote = each.xpath(".//p[@class='quote']/span/text()").extract()
if len(quote) != 0:
item['quote'] = quote[0]
yield item
if self.offset < 225:
self.offset += 25
yield scrapy.Request(self.url + str(self.offset), callback = self.parse)
第九步:在settings.py文件里设置管道文件。
ITEM_PIPELINES = {
'douban.pipelines.DoubanPipeline': 300,
}
第十步:创建 MongoDB 数据库"Douban"和存放爬虫数据的表"doubanmovies"。
在MongoDB中创建一个叫"Douban"的库。
MongoDB 创建数据库的语法格式如下:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
备注:刚创建的数据库 Douban并不在数据库的列表中, 要显示它,我们需要向 Douban 数据库插入一些数据或者创建表。
创建表:db.createCollection("doubanmovies")
语法格式:
db.createCollection(name, options)
创建表完成,再去查 MongoDB 中的库就显示了 Douban 库。
查看表:show collections
第十一步:在settings.py文件里配置 MongoDB 连接配置项。
# MONGODB 主机名
MONGODB_HOST = "127.0.0.1"
# MONGODB 端口号
MONGODB_PORT = 27017
# 数据库名称
MONGODB_DBNAME = "Douban"
# 存放数据的表名称
MONGODB_SHEETNAME = "doubanmovies"
第十二步: 编写 pipelines 管道文件(把数据存储到 MongoDB)。
import pymongo
from scrapy.conf import settings
class DoubanPipeline(object):
def __init__(self):
host = settings["MONGODB_HOST"]
port = settings["MONGODB_PORT"]
dbname = settings["MONGODB_DBNAME"]
sheetname= settings["MONGODB_SHEETNAME"]
# 创建MONGODB数据库链接
client = pymongo.MongoClient(host = host, port = port)
# 指定数据库
mydb = client[dbname]
# 存放数据的数据库表名
self.sheet = mydb[sheetname]
def process_item(self, item, spider):
data = dict(item)
self.sheet.insert(data)
return item
第十三步: 执行run.py文件,运行爬虫。
第十四步: 查看 MongoDB 数据库。
显示的只是一部分数据(Type "it" for more),如果想看完整的数据,可以通过 MongoDB 数据库自带的图形化客户端工具(MongoDB Compass Community)查看。
1.2 进阶篇案例二
案例:使用下载中间件(Downloader Middlewares)改写爬取豆瓣电影top250案例
案例步骤:
第一步:创建爬虫项目。
在 dos下切换到目录
D:scrapy_project
新建一个新的爬虫项目:scrapy startproject douban2
第二步:创建爬虫。
在 dos下切换到目录。
D:scrapy_projectdouban2douban2spiders
用命令 scrapy genspider doubanmovie2 "movie.douban.com" 创建爬虫。
第三步: 开始前的准备工作。
(一)、在 scrapy.cfg 同级目录下创建 pycharm 调试脚本 run.py,内容如下:
# -*- coding: utf-8 -*-
from scrapy import cmdline
cmdline.execute("scrapy crawl doubanmovie".split())
(二)、修改 settings 中的 ROBOTSTXT_OBEY = True 参数为 False,因为默认为 True,就是要遵守 robots.txt 的规则, robots.txt 是遵循 Robot协议 的一个文件,它保存在网站的服务器中,它的作用是,告诉搜索引擎爬虫,本网站哪些目录下的网页不希望你进行爬取收录。在 Scrapy 启动后,会在第一时间访问网站的 robots.txt 文件,然后决定该网站的爬取范围。查看 robots.txt 可以直接网址后接 robots.txt 即可。
例如百度:https://www.baidu.com/robots.txt
修改 settings 文件。
(三)不需要模拟登陆,settings.py 里的 COOKIES_ENABLED ( Cookies中间件) 设置禁用状态。
COOKIES_ENABLED = False
备注:截图使用的是案例一,步骤参考案例一。
第四步: 定义 Item,编写 items.py 文件。
import scrapy
class DoubanItem(scrapy.Item):
# 电影标题
title = scrapy.Field()
# 电影信息
bd = scrapy.Field()
# 豆瓣评分
star = scrapy.Field()
# 脍炙人口的一句话
quote = scrapy.Field()
第五步: 编写爬虫文件。
import scrapy,sys,os
path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(path)
from douban.items import DoubanItem
class DoubamovieSpider(scrapy.Spider):
name = "doubanmovie"
allowed_domains = ["movie.douban.com"]
offset = 0
url = "https://movie.douban.com/top250?start="
start_urls = (
url + str(offset),
)
def parse(self, response):
item = DoubanItem()
movies = response.xpath("//div[@class='info']")
for each in movies:
# 电影标题
item['title'] = each.xpath(".//span[@class='title'][1]/text()").extract()[0]
# 电影信息
item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]
# 豆瓣评分
item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]
# 脍炙人口的一句话
quote = each.xpath(".//p[@class='quote']/span/text()").extract()
if len(quote) != 0:
item['quote'] = quote[0]
yield item
if self.offset < 225:
self.offset += 25
yield scrapy.Request(self.url + str(self.offset), callback = self.parse)
第六步:在settings.py文件里设置管道文件。
ITEM_PIPELINES = {
'douban.pipelines.DoubanPipeline': 300,
}
第七步:创建 MongoDB 数据库"Douban"和存放爬虫数据的表"doubanmovies"。
在MongoDB中创建一个叫"Douban"的库。
MongoDB 创建数据库的语法格式如下:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
备注:刚创建的数据库 Douban 并不在数据库的列表中, 要显示它,我们需要向 Douban 数据库插入一些数据或者创建表。
创建表:db.createCollection("doubanmovies")
语法格式:
db.createCollection(name, options)
创建表完成,再去查 MongoDB 中的库就显示了 Douban 库。
查看表:show collections
第八步:在settings.py文件里配置 MongoDB 连接配置项。
# MONGODB 主机名
MONGODB_HOST = "127.0.0.1"
# MONGODB 端口号
MONGODB_PORT = 27017
# 数据库名称
MONGODB_DBNAME = "Douban"
# 存放数据的表名称
MONGODB_SHEETNAME = "doubanmovies"
第九步: 编写 pipelines 管道文件(把数据存储到 MongoDB)。
import pymongo
from scrapy.conf import settings
class DoubanPipeline(object):
def __init__(self):
host = settings["MONGODB_HOST"]
port = settings["MONGODB_PORT"]
dbname = settings["MONGODB_DBNAME"]
sheetname= settings["MONGODB_SHEETNAME"]
# 创建MONGODB数据库链接
client = pymongo.MongoClient(host = host, port = port)
# 指定数据库
mydb = client[dbname]
# 存放数据的数据库表名
self.sheet = mydb[sheetname]
def process_item(self, item, spider):
data = dict(item)
self.sheet.insert(data)
return item
第十步: 在settings.py文件里添加下载中间件(Downloader Middlewares)字段。
DOWNLOADER_MIDDLEWARES = {
'douban.middlewares.RandomUserAgent': 100,
'douban.middlewares.RandomProxy': 200,
}
USER_AGENTS = [
'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)',
'Opera/9.27 (Windows NT 5.2; U; zh-cn)',
'Opera/8.0 (Macintosh; PPC Mac OS X; U; en)',
'Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.0',
'Mozilla/5.0 (Linux; U; Android 4.0.3; zh-cn; M032 Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
'Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13'
]
PROXIES = [
{"ip_port" :"121.42.140.113:16816