Scrapy 爬虫完整案例-进阶篇
1.1 进阶篇案例一
案例:爬取豆瓣电影 top250( movie.douban.com/top250 )的电影数据,并保存在 MongoDB 中。
![dd46bdc0cdf62ed47d636456f38ac700.png](https://i-blog.csdnimg.cn/blog_migrate/8f7017a4ebaff07715f5a90fe2028f6b.jpeg)
案例步骤:
第一步:明确爬虫需要爬取的内容。
我们做爬虫的时候,需要明确需要爬取的内容,豆瓣电影 TOP 250,我们需要抓取每一部电影的名字,电影的描述信息(包括导演、主演、电影类型等等),电影的评分,以及电影中最经典或者脍炙人口的一句话。
例如:肖申克的救赎
![bd78ccdab8509d1d1a8f87d27d748dad.png](https://i-blog.csdnimg.cn/blog_migrate/4a2e4e98c98ab468b4d910c7d76d679c.jpeg)
电影的名字:肖申克的救赎。
电影信息(导演:弗兰克·德拉邦特;主演:蒂姆·罗宾斯 / 摩根·弗里曼 / 鲍勃·冈顿 / 威廉姆·赛德勒 / 克兰西·布朗 / 更多...;电影类型:剧情 / 犯罪。)
豆瓣电影评分:9.6。
脍炙人口的一句话:希望让人自由。
第二步:创建爬虫项目。
在 dos下切换到目录
D:scrapy_project
![6a6fc503be9fd351533e22e99fff8665.png](https://i-blog.csdnimg.cn/blog_migrate/004b29abe3af241b1b22931d8f9d6113.jpeg)
新建一个新的爬虫项目:scrapy startproject douban
![295ef0f43233914ffb55f5aec5f4a3f1.png](https://i-blog.csdnimg.cn/blog_migrate/55df8643f88219e6e5964ec739fdcc25.jpeg)
![8c2987ce4c650efc73b125148f2219ca.png](https://i-blog.csdnimg.cn/blog_migrate/f0f2b6b435be883abd2b8d0110b6a162.jpeg)
第三步:创建爬虫。
在 dos下切换到目录。
D:scrapy_projectdoubandoubanspiders
用命令 scrapy genspider doubanmovie "movie.douban.com" 创建爬虫。
![e36584f7fd8b822fab83c84acdecce06.png](https://i-blog.csdnimg.cn/blog_migrate/03f90e7f650b6298e86182a1b08e2c58.jpeg)
第四步: 开始前的准备工作。
(一)、在 scrapy.cfg 同级目录下创建 pycharm 调试脚本 run.py,内容如下:
# -*- coding: utf-8 -*-
from scrapy import cmdline
cmdline.execute("scrapy crawl doubanmovie".split())
![370a95de3e6df3c3c5c7e9eafe5a5726.png](https://i-blog.csdnimg.cn/blog_migrate/4d4199bd647ed5f333d96e7397d54f28.jpeg)
![89c66108e20153ff80a67c2abe71aadf.png](https://i-blog.csdnimg.cn/blog_migrate/86df06451a5af50c01b7854deba4e576.jpeg)
![1a24367b05cac19c9adcfc08026d14d1.png](https://i-blog.csdnimg.cn/blog_migrate/81c792290d55aa2850cd7a87b4e5acd6.jpeg)
(二)、修改 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 文件。
![2514bfa18cfbfddaa7e1aaa30995602b.png](https://i-blog.csdnimg.cn/blog_migrate/cc9b005fec4f461257d12de84de55bbc.jpeg)
(三)、settings.py 里添加 USER_AGENT。
![abf447543b7f40d846cd25ef45be3c5d.png](https://i-blog.csdnimg.cn/blog_migrate/ffa948e5f504951fa1e11d7b8cfeb906.jpeg)
(四)不需要模拟登陆,settings.py 里的 COOKIES_ENABLED ( Cookies中间件) 设置禁用状态。
COOKIES_ENABLED = False
![4d27f23e0e980c4de2ba0211c26d1cca.png](https://i-blog.csdnimg.cn/blog_migrate/326a93ac4376d98b9788c10be22a0f56.jpeg)
第五步: 定义 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]
![93995e47fac65030da9e8f1c0e125298.png](https://i-blog.csdnimg.cn/blog_migrate/fcf222aeacb5624fbfd7a1551cef60cb.jpeg)
# 电影信息
item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]
![9b5f074c43a1046226b64b72fb229678.png](https://i-blog.csdnimg.cn/blog_migrate/3262a6b55c70373a0f92a36deb65bbc0.jpeg)
# 豆瓣评分
item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]
![dbf10e207f1f1f50ab0f0be0772a3f7c.png](https://i-blog.csdnimg.cn/blog_migrate/9756e52ab0b7dea95d003a83535f2933.jpeg)
# 脍炙人口的一句话
quote = each.xpath(".//p[@class='quote']/span/text()").extract()
![7c74051c262ac3ec9781c1f7a82efee6.png](https://i-blog.csdnimg.cn/blog_migrate/fa00f6e34c761b5b50159cb305fcf7ab.jpeg)
备注:extract()返回的是一个列表,列表里的每个元素是一个对象,extract()把这些对象转换成 Unicode 字符串。
第七步: 分析网站分页的 URL 规律。
![1de2b1aeb13fd38a591c2b9cbc294f9a.png](https://i-blog.csdnimg.cn/blog_migrate/7e05dc5f39a6155cf694e702ffcdc63f.jpeg)
第一页的链接地址:
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,
}
![fae9a866740fb25805dab5a5cf8884ff.png](https://i-blog.csdnimg.cn/blog_migrate/6828b2572672b917c90a71d3ab501141.jpeg)
第十步:创建 MongoDB 数据库"Douban"和存放爬虫数据的表"doubanmovies"。
在MongoDB中创建一个叫"Douban"的库。
![ea637d478df4011ff458dfcece4c6d88.png](https://i-blog.csdnimg.cn/blog_migrate/1b95e8d25d051e3e1e91180353db11bc.jpeg)
MongoDB 创建数据库的语法格式如下:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
![59b583c818ff503087f056ba918625ee.png](https://i-blog.csdnimg.cn/blog_migrate/cc0bf4cef0390386bf950436085f6702.jpeg)
备注:刚创建的数据库 Douban并不在数据库的列表中, 要显示它,我们需要向 Douban 数据库插入一些数据或者创建表。
创建表:db.createCollection("doubanmovies")
语法格式:
db.createCollection(name, options)
![68385e5ade83a1d7862c0a4453e1c070.png](https://i-blog.csdnimg.cn/blog_migrate/4c75e115305d408134bf0ba10152ab43.jpeg)
创建表完成,再去查 MongoDB 中的库就显示了 Douban 库。
![5346328aafa3e79fed95ce25a06dc3c7.png](https://i-blog.csdnimg.cn/blog_migrate/6e6c4f8596479f8c28a33baa25de3293.jpeg)
查看表:show collections
![292ad7469e16c8b3f31ec6c6fbc522a6.png](https://i-blog.csdnimg.cn/blog_migrate/b547f9063f5598c8153935cfbd950271.jpeg)
第十一步:在settings.py文件里配置 MongoDB 连接配置项。
# MONGODB 主机名
MONGODB_HOST = "127.0.0.1"
# MONGODB 端口号
MONGODB_PORT = 27017
# 数据库名称
MONGODB_DBNAME = "Douban"
# 存放数据的表名称
MONGODB_SHEETNAME = "doubanmovies"
![5ab3a110c12bd3b7c377a498472ca520.png](https://i-blog.csdnimg.cn/blog_migrate/99f5c986669f5bea250bc610161df7ec.jpeg)
第十二步: 编写 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文件,运行爬虫。
![62c5a4e7f9347a949608ba54d9cfd888.png](https://i-blog.csdnimg.cn/blog_migrate/10371a80fa0e8b29337f6065d051ac06.jpeg)
![7df5f247225b68856a08913aa90b97ab.png](https://i-blog.csdnimg.cn/blog_migrate/6a39fb9c73f0276b5bbec8c6754f5860.jpeg)
第十四步: 查看 MongoDB 数据库。
![157da78592c597e01b3128a3e6be6573.png](https://i-blog.csdnimg.cn/blog_migrate/03545795e5c52e47613427589809a313.jpeg)
显示的只是一部分数据(Type "it" for more),如果想看完整的数据,可以通过 MongoDB 数据库自带的图形化客户端工具(MongoDB Compass Community)查看。
![210cd009f704d90fb8eed84035dd78b1.png](https://i-blog.csdnimg.cn/blog_migrate/423676e6b18ea1fcf1e13bfb1c8925f3.jpeg)
1.2 进阶篇案例二
案例:使用下载中间件(Downloader Middlewares)改写爬取豆瓣电影top250案例
案例步骤:
第一步:创建爬虫项目。
在 dos下切换到目录
D:scrapy_project
![4b6c3d77a501e58ff273e8b5caf68ed6.png](https://i-blog.csdnimg.cn/blog_migrate/72fe413c19aa8285aaf670ff73a55f47.jpeg)
新建一个新的爬虫项目:scrapy startproject douban2
![18dfbd3b8fc7422a7dd499c0ac7a0340.png](https://i-blog.csdnimg.cn/blog_migrate/4c901df177c6332d5cd10db8d8e7a81b.jpeg)
![c7dd7578efcdb3cde28d7b63e642df7e.png](https://i-blog.csdnimg.cn/blog_migrate/1b156518811f0a4d00ad0c00f3ed3df0.jpeg)
第二步:创建爬虫。
在 dos下切换到目录。
D:scrapy_projectdouban2douban2spiders
用命令 scrapy genspider doubanmovie2 "movie.douban.com" 创建爬虫。
![f02821e4ad4fff30190c5c97ca1028e5.png](https://i-blog.csdnimg.cn/blog_migrate/1cba99776915d6778955ab49b454b23e.jpeg)
第三步: 开始前的准备工作。
(一)、在 scrapy.cfg 同级目录下创建 pycharm 调试脚本 run.py,内容如下:
# -*- coding: utf-8 -*-
from scrapy import cmdline
cmdline.execute("scrapy crawl doubanmovie".split())
![931ad2d431431f27f8f7846ba2645439.png](https://i-blog.csdnimg.cn/blog_migrate/f1c1e79851fd3ae76f2910050a33c584.jpeg)
![0dbf9fd039ddd7a9a2b4b1ffbf4509a4.png](https://i-blog.csdnimg.cn/blog_migrate/0bd453c57fc2c51f50ffde30f91bf97a.jpeg)
![96f893ee08b8f9533d77088a67ced2fa.png](https://i-blog.csdnimg.cn/blog_migrate/8d679cde2ac7aede9893e28835a4cfc1.jpeg)
(二)、修改 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 文件。
![7fbab09b6c9ae8b82efeba755cbdaa71.png](https://i-blog.csdnimg.cn/blog_migrate/ee8537d4f83f7e5e4dfe2dae0ab82a56.jpeg)
(三)不需要模拟登陆,settings.py 里的 COOKIES_ENABLED ( Cookies中间件) 设置禁用状态。
COOKIES_ENABLED = False
![811bfce759da954cf787e0c6f4199b73.png](https://i-blog.csdnimg.cn/blog_migrate/670c2c780b232016f90c0b6ad6924646.jpeg)
备注:截图使用的是案例一,步骤参考案例一。
第四步: 定义 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,
}
![8f83df969eb7bb9c875ac7a709e9ce50.png](https://i-blog.csdnimg.cn/blog_migrate/7cae3abb13b53663186505a6ffae477d.jpeg)
第七步:创建 MongoDB 数据库"Douban"和存放爬虫数据的表"doubanmovies"。
在MongoDB中创建一个叫"Douban"的库。
![a5c78bf03fd63174d7350b854c428375.png](https://i-blog.csdnimg.cn/blog_migrate/3c21335ba6080b0368404746d1491154.jpeg)
MongoDB 创建数据库的语法格式如下:
use DATABASE_NAME
如果数据库不存在,则创建数据库,否则切换到指定数据库。
![d236e5740570ef7054df03b00cda28de.png](https://i-blog.csdnimg.cn/blog_migrate/5494cd7d02ca1f2a18778c435995aeb1.jpeg)
备注:刚创建的数据库 Douban 并不在数据库的列表中, 要显示它,我们需要向 Douban 数据库插入一些数据或者创建表。
创建表:db.createCollection("doubanmovies")
语法格式:
db.createCollection(name, options)
![4f0f76c4afee9b1e54d64073dcfd9005.png](https://i-blog.csdnimg.cn/blog_migrate/0d1fbbca05a8e23d20269a1416ae25bf.jpeg)
创建表完成,再去查 MongoDB 中的库就显示了 Douban 库。
![c17b393785266c50bd3b2bb2419d512e.png](https://i-blog.csdnimg.cn/blog_migrate/8e4f4617eccdfd37378c544e96fd25c5.jpeg)
查看表:show collections
![2a7d8d480449151bc88505d5da4b1584.png](https://i-blog.csdnimg.cn/blog_migrate/5c0de5f90d342076c113e24a3f67aefc.jpeg)
第八步:在settings.py文件里配置 MongoDB 连接配置项。
# MONGODB 主机名
MONGODB_HOST = "127.0.0.1"
# MONGODB 端口号
MONGODB_PORT = 27017
# 数据库名称
MONGODB_DBNAME = "Douban"
# 存放数据的表名称
MONGODB_SHEETNAME = "doubanmovies"
![86d8abb662f6ac5f9b8cdeeefd04b14e.png](https://i-blog.csdnimg.cn/blog_migrate/4f56c666a5c3d7c4946622af141d5fae.jpeg)
第九步: 编写 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