前言(目的)
本文为scrapy爬虫的入门文章,作者尽量将自己刚开始学习所遇到的问题都还原出来,过程尽量写得详细详细再详细。希望通过这篇文章来记录自己刚开始学习爬虫所踩过的一些坑,同时记录下自己处理和解决问题的思路,便于和大家分享交流,同时也希望读者能仅仅只通过这一篇文章,就搭建出一个 demo 可以立马上手跑起来。
在本篇文章中,作者先简单的介绍了爬虫的基本概念和 scrapy 爬虫框架,接着以豆瓣电影TOP250为例,详细讲述 scrapy 的实际运用。由于作者水平有限,若有错误或不恰当之处,还望不吝批评指正。
爬虫是什么
网络爬虫(crawler)又被称为网络蜘蛛(spider),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
scrapy概述
scrapy 是一个为了爬取网站数据,提取结构性数据而编写的基于Python语言的应用框架。可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。
教程推荐看极客学院翻译的 scrapy 中文指南 http://wiki.jikexueyuan.com/project/scrapy/
安装指南
第一步:安装Python3
建议下载 Anaconda 或者 Miniconda (https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/)进行安装。Anaconda是一个用于科学计算的Python发行版,支持Linux,Mac,Windows,包含了很多流行的科学计算、数据分析的Python包。Miniconda 是一个 Anaconda 的轻量级替代,默认只包含了 Python 和 conda ,但是可以通过 pip 或者 conda 来安装所需要的包。
第二步:安装scrapy
pip install scrapy
或者
conda install scrapy
第三步:安装PyCharm
编译软件可以根据自己爱好进行选择。
##scrapy实战:豆瓣电影TOP250
第一步:创建项目
在你即将创建项目的位置,打开命令行窗口,输入下面的命令,即可创建一个scrapy项目模板。
scrapy startproject project_name
在本例子中就是
scrapy startproject doubanmovie
第二步:scrapy项目的文件结构
- scrapy.cfg:项目的配置文件
- items.py:项目中的 item 文件
- pipelines.py:项目中的 pipelines 文件
- settings.py:项目的设置文件
- spiders/:放置 spider 代码的文件夹
第三步:定义 Item
Item 是保存爬取到的数据的容器;其使用方法和 Python 字典类似,并且提供了额外保护机制来避免拼写错误导致的未定义字段错误。
以豆瓣电影TOP250 https://movie.douban.com/top250 为例,我们需要抓取每一部电影的名字,电影的描述信息(包括导演、主演、电影类型等等),电影的评分,以及电影中最经典或者说脍炙人口的一句话。那么 items.py 文件如下。
import scrapy
class DoubanmovieItem(scrapy.Item):
title = scrapy.Field() # 电影名字
movieInfo = scrapy.Field() # 电影的描述信息,包括导演、主演、电影类型等等
star = scrapy.Field() # 电影评分
quote = scrapy.Field() # 电影中最经典或者说脍炙人口的一句话
pass
第三步:编写第一个爬虫(Spider)
Spider 是用户编写用于从单个网站(或者一些网站)爬取数据的类。包含以下三个属性:
name
:用于区别 spider,该名字必须是唯一的。start_urls
:包含了 spider 在启动时进行爬取的 URL 列表。因此,第一个被获取到的页面将是其中之一。后续的 URL 则从初始的 URL 获取到的数据中提取。parse()
是 spider 的一个方法。被调用时,每个初始 URL 完成下载后生成的 response 对象将会作为唯一的参数传递给该函数。该方法负责解析返回的数据(response data),提取数据(生成 item)以及生成需要进一步处理的 URL 的 Request 对象。
以下为豆瓣TOP250的 Spider 代码,保存在 doubanmovie/spiders 目录下的 doubanspider.py 文件中。
import scrapy
from scrapy.http import Request
from scrapy.selector import Selector
from doubanmovie.items import DoubanmovieItem
from urllib.parse import urljoin
class Douban(scrapy.spiders.Spider):
name = "douban"
allowed_domains = ["douban.com"]
# redis_key = 'douban:start_urls'
start_urls = ['https://movie.douban.com/top250']
def parse(self, response):
item = DoubanmovieItem()
selector = Selector(response)
Movies = selector.xpath('//div[@class="info"]')
for eachMovie in Movies:
title = eachMovie.xpath('div[@class="hd"]/a/span/text()').extract() # 多个span标签
fullTitle = "".join(title) # 将多个字符串无缝连接起来
movieInfo = eachMovie.xpath('div[@class="bd"]/p/text()').extract()
star = eachMovie.xpath('div[@class="bd"]/div[@class="star"]/span/text()').extract()[0]
quote = eachMovie.xpath('div[@class="bd"]/p[@class="quote"]/span/text()').extract()
# quote可能为空,因此需要先进行判断
if quote:
quote = quote[0]
else:
quote = ''
item['title'] = fullTitle
item['movieInfo'] = ';'.join(movieInfo)
item['star'] = star
item['quote'] = quote
yield item
nextLink = selector.xpath('//span[@class="next"]/link/@href').extract()
# 第10页是最后一页,没有下一页的链接
if nextLink:
nextLink = nextLink[0]
yield Request(urljoin(response.url, nextLink), callback=self.parse)
第四步:在settings文件中设置用户代理
USER_AGENT = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
第五步:运行爬虫
方法一:打开命令行,进入到项目路径下,然后运行命令 scrapy crawl douban
方法二:在items.py的同级目录下,创建 main.py ,如图所示。
其中代码如下:
from scrapy.cmdline import execute
execute("scrapy crawl douban".split())
推荐使用第二种方法,便于在集成开发环境中进行调试。
如何将爬取的数据存储在MySQL中
第一步 安装MySQL 和可视化工具Navicat for MySql
请参考博文http://blog.csdn.net/firewall5788/article/details/73526387
第二步 在MySQL中建立数据库
数据库名字为doubanmovie
新建表doubantop250
字段如下图所示。
注意,此处ID设置为自动递增
第三步 安装pymysql
在Python 2.x 中驱动文件是 mysqldb
,但是在Python3.x中已经不再支持那个组件了 。取而代之的是 pymysql
。
安装方法: pip install pymysql
或 conda install pymysql
第四步 在项目的settings.py文件中添加如下代码
MYSQL_HOST = 'localhost' # 数据库地址
MYSQL_DBNAME = 'doubanmovie' # 数据库名字
MYSQL_USER = 'root' # 数据库登录名
MYSQL_PASSWD = '123456' # 数据库登录密码
# 数据传输
ITEM_PIPELINES = {
'doubanmovie.pipelines.DoubanmoviePipeline': 301,
}
第五步 在项目的pipelines.py文件中添加如下代码
import pymysql
from doubanmovie import settings
class DoubanmoviePipeline(object):
def __init__(self):
self.connect = pymysql.connect(
host=settings.MYSQL_HOST,
db=settings.MYSQL_DBNAME,
user=settings.MYSQL_USER,
passwd=settings.MYSQL_PASSWD,
charset='utf8',
use_unicode=True)
self.cursor = self.connect.cursor()
def process_item(self, item, spider):
try:
self.cursor.execute(
"""insert into doubantop250(title,movieInfo,star,quote)
value (%s,%s,%s,%s)""",
(item['title'],
item['movieInfo'],
item['star'],
item['quote']))
self.connect.commit()
except Exception as err:
print("重复插入了==>错误信息为:" + str(err))
return item
至此,便将爬取的数据保存到了数据库中。如下图所示。