[置顶] 利用Scrapy爬取1905电影网

时间:2022-09-18 16:29:05

本文将从以下几个方面讲解Scrapy爬虫的基本操作

  • Scrapy爬虫介绍
  • Scrapy安装
  • Scrapy实例——爬取1905电影网
  • 相关资料

Scrapy 爬虫介绍

Scrapy是Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。

Scrapy 使用 Twisted这个异步网络库来处理网络通讯,架构清晰,并且包含了各种中间件接口,可以灵活的完成各种需求。整体架构如下图所示:

[置顶]        利用Scrapy爬取1905电影网

从上图中可以看到,Scrapy已经帮我们处理好了Downloader以及Scheduler。作为轻量级用户,我们完全不用关心爬虫是如何调度及下载的,只需要关注爬虫的爬去规则(Spiders)以及如何存储(Item Pipeline)。

Scrapy的安装

网上有许多关于Scrapy安装的博客,大家自行搜索,我是采用pip的安装方式

pip install scrapy

如果使用pip安装时遇到 KeyError: u’\u6e29’ 的问题,可以参考我的博客

python2.7 pip install 报错KeyError: u’\u6e29’解决方案

Scrapy 实例

爬虫任务介绍

这次要爬去1905电影网的所有中国电影,共14499部电影
下图为目录页,每个目录页有30个电影,共有486个目录页
[置顶]        利用Scrapy爬取1905电影网

下图为需要保存的电影页面,我们将其保存到本地,以后再解析
[置顶]        利用Scrapy爬取1905电影网

我们观察到目录页url是有规律的,
第一页 http://www.1905.com/mdb/film/list/country-China/o0d0p0.html
第二页 http://www.1905.com/mdb/film/list/country-China/o0d0p1.html
最后页 http://www.1905.com/mdb/film/list/country-China/o0d0p484.html
因此我们每次替换上面url中黑体的部分即可。

整个爬虫的逻辑为
1. 构建所有目录页url
2. 爬取目录页,并分析出当前目录页中的电影页url
3. 爬取电影页,并保存

创建爬虫

在开始爬取之前,必须创建一个新的Scrapy项目。 利用cmd进入打算存储代码的目录中,然后输入命令scrapy startproject movie1905构建爬虫项目,其中 movie1905 项目名,可自定义。

该命令将会创建包含下列内容的movie1905目录:

movie1905/
scrapy.cfg
movie1905/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
...

其中settings.py是项目的配置文件,spiders目录是放置爬虫的目录,pipelines.py是用于存数据的文件,items.py是爬虫爬取数据的容器

定义Item

item 是保存爬取到的数据的容器,我们根据自己的需要定义Item

import scrapy
class Movie1905Item(scrapy.Item):

url = scrapy.Field() # url
html = scrapy.Field() # 爬取下来的网页内容
filename = scrapy.Field() # 网页存储在本地的文件名

撰写爬虫

这个爬虫需要在spiders目录里新建一个.py文件

class Movie(scrapy.Spider):
name = "chineseMovie"
allowed_domains = ["1905.com"]

其中name 是用于在命令行调用爬虫时作为爬虫区分的标识,简单说就是爬虫的名字,该名字必须唯一!
allowed_domains 是爬虫允许爬去的域名,如果不在该域名中则不爬取。
应该来说还应有一个start_urls 作为Spider在启动时进行爬取的url列表,但考虑到我们需要爬取的url有一定的规则,因此用一个中间件代替,如下所示:

    def start_requests(self):
basic_url = "http://www.1905.com/mdb/film/list/country-China/o0d0p%s.html"

start,end = 0,485
for i in range(start,end):
url = basic_url.replace("%s",str(i))
yield scrapy.http.Request(url,self.parse)

分析网页时对于目录页与电影页需要区别对待。

对于目录页的处理

首先对于目录页我们需要分析出当前目录页中的电影页url,并将该url交给scrapy去进行接下来的处理

    def parse(self, response):
sel = Selector(response)
urls = sel.xpath('//ul[@class="inqList pt18"]/li/a/@href').extract()

for url in urls:
url = "http://www.1905.com" + url
yield scrapy.http.Request(url,self.parse_movie)

注意到,提取url标签时我们采用xpath进行标签定位,关于xpath的介绍可以看这里
这里还有一种更简单的xpath定位方法,我们使用chrome浏览器,右键审查元素找到我们想要的标签,在该标签上邮件copy,选择copy xpath,根据该结果进行适当调整即可,如下图所示:
[置顶]        利用Scrapy爬取1905电影网

对于电影页的处理

根据前面所说,我们暂时不分析电影页中的内容,仅仅是将其存入本地

    def parse_movie(self, response):
item = Movie1905Item()
item['url'] = response.url
item['html'] = response.body
item['filename'] = "movie_" + hashlib.sha1(response.url).hexdigest() + ".txt"

print response.url
return item

保存数据

爬虫处理完数据后,返回一个item,scrapy看到返回结果是个item就会根据配置文件将其交给相应的pipeline的process_item方法进行数据的保存工作,这里没有什么太多可说的,大家根据自己的定义写就可以了

class Movie1905Pipeline(object):
db = "movie" # 数据库名
filePath = "E://crawlerFile//movie//" # 爬去下来的文件保存目录地址

def __init__(self):
self.SQLconn = SqlConnector(db=self.db) # 我自己封装的数据库类

def process_item(self, item, spider):
self.save_in_File(item)
self.save_in_DB(item)
return item

# 存入文件
def save_in_File(self,item):
file_object = open(self.filePath + item['filename'],'w')
file_object.write(item['html'])
file_object.close()

# 存入数据库
def save_in_DB(self,item):
query = "insert into movie(url,filename) values(%s,%s)"
query = self.SQLconn.generateQuery(query,[item['url'],item["filename"]])
self.SQLconn.insert(query)

配置文件

我们可以利用配置文件对我们的爬虫进行深层定制,现在这个spider只需要增加两个配置

DOWNLOAD_HANDLERS = {'s3': None,}
ITEM_PIPELINES=['movie1905.pipelines.Movie1905Pipeline']

第一行我暂时也不知道是做什么用的,但没有这行爬虫不会运行
第二行是定义爬虫的Pipeline

爬虫运行

在cmd内进入同scrapy.cfg同一级目录中,运行

scrapy crawl chineseMovie

运行结果如下图所示
[置顶]        利用Scrapy爬取1905电影网

相关资料

【1】该爬虫源代码
【2】Scrapy手册
【3】xPath资料