文章目录
一、分析网页
目标URL:https://movie.douban.com/top250?start=0&filter=
每一页有25条电影信息,总共10页。检查网页可以发现,每条电影的详细信息在 ol class=“grid_view” 下的 li 标签里。
翻页查看网页可以发现URL变化的规律,在第几页,URL为:f’https://movie.douban.com/top250?start={(page-1) * 25} &filter=’
在写scrapy爬虫时,构造出10页的URL,生成10次请求。
二、scrapy爬虫
编写scrapy爬虫,电影信息保存到csv文件,电影海报保存到本地文件夹。
创建项目
代码语言:txt复制scrapy startproject Douban_movie_top250
cd Douban_movie_top250
scrapy genspider Douban movie.douban.com
构造请求
Douban.py中定义 start_requests() 方法,爬取十页的电影信息,生成10次请求,代码如下:
代码语言:txt复制 def start_requests(self):
for i in range(10):
url = f'https://movie.douban.com/top250?start={25 * i}&filter='
yield Request(url=url, callback=self.parse)
编写 items.py
代码语言:txt复制import scrapy
class DoubanMovieTop250Item(scrapy.Item):
name = scrapy.Field()
pic_link = scrapy.Field()
rank = scrapy.Field()
director_actor = scrapy.Field()
info = scrapy.Field()
rating_score = scrapy.Field()
rating_num = scrapy.Field()
introduce = scrapy.Field()
编写 Douban.py
Spider类定义了如何爬取某个(或某些)网站,包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(抓取item)
代码语言:txt复制import scrapy
from scrapy import Request
from Douban_movie_top250.items import DoubanMovieTop250Item
class DoubanSpider(scrapy.Spider):
name = 'Douban'
allowed_domains = ['movie.douban.com']
def start_requests(self):
for i in range(10):
url = f'https://movie.douban.com/top250?start={25 * i}&filter='
yield Request(url=url, callback=self.parse)
def parse(self, response, **kwargs):
for li in response.xpath("//ol[@class='grid_view']/li"):
item = DoubanMovieTop250Item()
item['rank'] = li.xpath(".//div[@class='pic']/em/text()").extract_first()
item['name'] = li.xpath(".//div[@class='hd']/a/span[@class='title']/text()").extract_first()
item['pic_link'] = li.xpath(".//div[@class='pic']/a/img/@src").extract_first()
item['info'] = li.xpath(".//div[@class='bd']/p/text()").extract()[1].strip()
item['director_actor'] = li.xpath(".//div[@class='bd']/p/text()").extract_first().strip()
item['rating_score'] = li.xpath(".//div[@class='star']/span[2]/text()").extract_first()
item['rating_num'] = li.xpath(".//div[@class='star']/span[4]/text()").extract_first()
item['introduce'] = li.xpath(".//p[@class='quote']/span/text()").extract_first()
yield item
编写管道文件 pipelines.py
还要将电影海报一起下载下来,所以需要编写管道文件 pipelines.py,Scrapy 提供了专门处理下载的 Pipeline,包括文件下载和图片下载。下载文件和图片的原理与抓取页面的原理一样,因此下载过程支持异步和多线程,十分高效。
代码语言:txt复制from scrapy.pipelines.images import ImagesPipeline # scrapy图片下载器
from scrapy import Request
from scrapy.exceptions import DropItem
class DoubanMovieTop250Pipeline(ImagesPipeline):
# 请求下载图片
def get_media_requests(self, item, info):
yield Request(item['pic_link'], meta={'name': item['name']})
def item_completed(self, results, item, info):
# 分析下载结果并剔除下载失败的图片
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
return item
# 重写file_path方法,将图片以原来的名称和格式进行保存
def file_path(self, request, response=None, info=None):
name = request.meta['name'] # 接收上面meta传递过来的图片名称
file_name = name '.jpg' # 添加图片后缀名
return file_name
配置文件 settings.py
代码语言:txt复制# settings.py
BOT_NAME = 'Douban_movie_top250'
SPIDER_MODULES = ['Douban_movie_top250.spiders']
NEWSPIDER_MODULE = 'Douban_movie_top250.spiders'
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 10
# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.25
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'Douban_movie_top250.pipelines.DoubanMovieTop250Pipeline': 300,
}
IMAGES_STORE = './Douban_pic'
运行程序
代码语言:txt复制# 切换路径到img_spider的目录
scrapy crawl Douban -o movies_info.csv
运行效果如下:
scrapy爬虫在 2020-08-28 16:56:14启动,输出了 Scrapy的版本和一些配置信息,之后爬虫一边爬取一边下载,下载速度非常快。
2020-08-28 16:56:45 scrapy爬虫完成抓取。
运行结果如下:
三、处理数据
用scrapy框架爬取电影信息时,支持异步、并发,爬取效率很高,但输出到CSV文件里列名并没有按照 item 赋值时的顺序,每行的电影信息页没有按照排名排序,将数据处理一下并重新保存到Excel。
代码语言:txt复制import pandas as pd
df4 = pd.read_csv('movies_info.csv')
cols = df4.columns[[5, 3, 0, 1, 6, 7, 2, 4]] # 交换列的位置 自定义
new_df4 = df4[cols]
new_df4.sort_values(by='rank', inplace=True) # 按排名排序
new_df4.to_excel('moives_info.xlsx', index=False) # 重新保存到Excel
运行效果如下:
作者:叶庭云 微信公众号:修炼Python CSDN:https://yetingyun.blog.csdn.net/ 本文仅用于交流学习,未经作者允许,禁止转载,更勿做其他用途,违者必究。 觉得文章对你有帮助、让你有所收获的话,期待你的点赞呀,不足之处,也可以在评论区多多指正。