前言(目的)
本文為scrapy爬蟲的入門文章,作者盡量將自己剛開始學習所遇到的問題都還原出來,過程盡量寫得詳細詳細再詳細。希望通過這篇文章來記錄自己剛開始學習爬蟲所踩過的一些坑,同時記錄下自己處理和解決問題的思路,便于和大家分享交流,同時也希望讀者能僅僅只通過這一篇文章,就搭建出一個 demo 可以立馬上手跑起來。
在本篇文章中,作者先簡單的介紹了爬蟲的基本概念和 scrapy 爬蟲框架,接著以豆瓣電影TOP250為例,詳細講述 scrapy 的實際運用。由于作者水平有限,若有錯誤或不恰當之處,還望不吝批評指正。
爬蟲是什么
網(wǎng)絡爬蟲(crawler)又被稱為網(wǎng)絡蜘蛛(spider),是一種按照一定的規(guī)則,自動地抓取萬維網(wǎng)信息的程序或者腳本。
scrapy概述
scrapy 是一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的基于Python語言的應用框架。可以應用在包括數(shù)據(jù)挖掘,信息處理或存儲歷史數(shù)據(jù)等一系列的程序中。
教程推薦看極客學院翻譯的 scrapy 中文指南 http://wiki.jikexueyuan.com/project/scrapy/
安裝指南
第一步:安裝Python3
建議下載 Anaconda 或者 Miniconda (https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/)進行安裝。Anaconda是一個用于科學計算的Python發(fā)行版,支持Linux,Mac,Windows,包含了很多流行的科學計算、數(shù)據(jù)分析的Python包。Miniconda 是一個 Anaconda 的輕量級替代,默認只包含了 Python 和 conda ,但是可以通過 pip 或者 conda 來安裝所需要的包。
第二步:安裝scrapy
pip install scrapy
或者
conda install scrapy
第三步:安裝PyCharm
編譯軟件可以根據(jù)自己愛好進行選擇。
scrapy實戰(zhàn):豆瓣電影TOP250
第一步:創(chuàng)建項目
在你即將創(chuàng)建項目的位置,打開命令行窗口,輸入下面的命令,即可創(chuàng)建一個scrapy項目模板。
scrapy startproject project_name
在本例子中就是
scrapy startproject doubanmovie
第二步:scrapy項目的文件結(jié)構(gòu)
- scrapy.cfg:項目的配置文件
- items.py:項目中的 item 文件
- pipelines.py:項目中的 pipelines 文件
- settings.py:項目的設置文件
- spiders/:放置 spider 代碼的文件夾
第三步:定義 Item
Item 是保存爬取到的數(shù)據(jù)的容器;其使用方法和 Python 字典類似,并且提供了額外保護機制來避免拼寫錯誤導致的未定義字段錯誤。
以豆瓣電影TOP250 https://movie.douban.com/top250 為例,我們需要抓取每一部電影的名字,電影的描述信息(包括導演、主演、電影類型等等),電影的評分,以及電影中最經(jīng)典或者說膾炙人口的一句話。那么 items.py 文件如下。
import scrapy
class DoubanmovieItem(scrapy.Item):
title = scrapy.Field() # 電影名字
movieInfo = scrapy.Field() # 電影的描述信息,包括導演、主演、電影類型等等
star = scrapy.Field() # 電影評分
quote = scrapy.Field() # 電影中最經(jīng)典或者說膾炙人口的一句話
pass
第三步:編寫第一個爬蟲(Spider)
Spider 是用戶編寫用于從單個網(wǎng)站(或者一些網(wǎng)站)爬取數(shù)據(jù)的類。包含以下三個屬性:
-
name:用于區(qū)別 spider,該名字必須是唯一的。 -
start_urls:包含了 spider 在啟動時進行爬取的 URL 列表。因此,第一個被獲取到的頁面將是其中之一。后續(xù)的 URL 則從初始的 URL 獲取到的數(shù)據(jù)中提取。 -
parse()是 spider 的一個方法。被調(diào)用時,每個初始 URL 完成下載后生成的 response 對象將會作為唯一的參數(shù)傳遞給該函數(shù)。該方法負責解析返回的數(shù)據(jù)(response data),提取數(shù)據(jù)(生成 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的同級目錄下,創(chuàng)建 main.py ,如圖所示。

其中代碼如下:
from scrapy.cmdline import execute
execute("scrapy crawl douban".split())
推薦使用第二種方法,便于在集成開發(fā)環(huán)境中進行調(diào)試。
如何將爬取的數(shù)據(jù)存儲在MySQL中
**第一步 安裝MySQL 和可視化工具Navicat for MySql **
請參考博文http://blog.csdn.net/firewall5788/article/details/73526387
第二步 在MySQL中建立數(shù)據(jù)庫
數(shù)據(jù)庫名字為doubanmovie
新建表doubantop250
字段如下圖所示。

注意,此處ID設置為自動遞增
第三步 安裝pymysql
在Python 2.x 中驅(qū)動文件是 mysqldb,但是在Python3.x中已經(jīng)不再支持那個組件了 。取而代之的是 pymysql 。
安裝方法: pip install pymysql 或 conda install pymysql
第四步 在項目的settings.py文件中添加如下代碼
MYSQL_HOST = 'localhost' # 數(shù)據(jù)庫地址
MYSQL_DBNAME = 'doubanmovie' # 數(shù)據(jù)庫名字
MYSQL_USER = 'root' # 數(shù)據(jù)庫登錄名
MYSQL_PASSWD = '123456' # 數(shù)據(jù)庫登錄密碼
# 數(shù)據(jù)傳輸
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
至此,便將爬取的數(shù)據(jù)保存到了數(shù)據(jù)庫中。如下圖所示。

附
該文章于2017年7月17日于CSDN上首次發(fā)表,2017年12月24日搬家至此!