Scrapy 爬蟲完整案例-進階篇

1 Scrapy 爬蟲完整案例-進階篇

1.1 進階篇案例一

案例:爬取豆瓣電影 top250( movie.douban.com/top250 )的電影數據,並保存在 MongoDB 中。

Scrapy 爬蟲完整案例-進階篇

案例步驟:

第一步:明確爬蟲需要爬取的內容。

我們做爬蟲的時候,需要明確需要爬取的內容,豆瓣電影 TOP 250,我們需要抓取每一部電影的名字,電影的描述信息(包括導演、主演、電影類型等等),電影的評分,以及電影中最經典或者膾炙人口的一句話。

例如:肖申克的救贖

Scrapy 爬蟲完整案例-進階篇

電影的名字:肖申克的救贖。

電影信息(導演:弗蘭克·德拉邦特;主演:蒂姆·羅賓斯 / 摩根·弗里曼 / 鮑勃·岡頓 / 威廉姆·賽德勒 / 克蘭西·布朗 / 更多...;電影類型:劇情 / 犯罪。)

豆瓣電影評分:9.6。

膾炙人口的一句話:希望讓人自由。

第二步:創建爬蟲項目。

在 dos下切換到目錄

D:\\scrapy_project

Scrapy 爬蟲完整案例-進階篇

新建一個新的爬蟲項目:scrapy startproject douban

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

第三步:創建爬蟲。

在 dos下切換到目錄。

D:\\scrapy_project\\douban\\douban\\spiders

用命令 scrapy genspider doubanmovie "movie.douban.com" 創建爬蟲。

Scrapy 爬蟲完整案例-進階篇

第四步: 開始前的準備工作。

(一)、在 scrapy.cfg 同級目錄下創建 pycharm 調試腳本 run.py,內容如下:

# -*- coding: utf-8 -*-

from scrapy import cmdline

cmdline.execute("scrapy crawl doubanmovie".split())

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

(二)、修改 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 文件。

Scrapy 爬蟲完整案例-進階篇

(三)、settings.py 裡添加 USER_AGENT。

Scrapy 爬蟲完整案例-進階篇

(四)不需要模擬登陸,settings.py 裡的 COOKIES_ENABLED ( Cookies中間件) 設置禁用狀態。

COOKIES_ENABLED = False

Scrapy 爬蟲完整案例-進階篇

第五步: 定義 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]

Scrapy 爬蟲完整案例-進階篇

# 電影信息

item['bd'] = each.xpath(".//div[@class='bd']/p/text()").extract()[0]

Scrapy 爬蟲完整案例-進階篇

# 豆瓣評分

item['star'] = each.xpath(".//div[@class='star']/span[@class='rating_num']/text()").extract()[0]

Scrapy 爬蟲完整案例-進階篇

# 膾炙人口的一句話

quote = each.xpath(".//p[@class='quote']/span/text()").extract()

Scrapy 爬蟲完整案例-進階篇

備註:extract()返回的是一個列表,列表裡的每個元素是一個對象,extract()把這些對象轉換成 Unicode 字符串。

第七步: 分析網站分頁的 URL 規律。

Scrapy 爬蟲完整案例-進階篇

第一頁的鏈接地址:

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,

}

Scrapy 爬蟲完整案例-進階篇

第十步: 創建 MongoDB 數據庫"Douban"和存放爬蟲數據的表"doubanmovies"。

MongoDB中創建一個叫"Douban"的庫。

Scrapy 爬蟲完整案例-進階篇

MongoDB 創建數據庫的語法格式如下:

use DATABASE_NAME

如果數據庫不存在,則創建數據庫,否則切換到指定數據庫。

Scrapy 爬蟲完整案例-進階篇

備註:剛創建的數據庫 Douban並不在數據庫的列表中, 要顯示它,我們需要向 Douban 數據庫插入一些數據或者創建表。

創建表:db.createCollection("doubanmovies")

語法格式:

db.createCollection(name, options)

Scrapy 爬蟲完整案例-進階篇

創建表完成,再去查 MongoDB 中的庫就顯示了 Douban 庫。

Scrapy 爬蟲完整案例-進階篇

查看錶:show collections

Scrapy 爬蟲完整案例-進階篇

第十一步: 在settings.py文件裡配置 MongoDB 連接配置項

# MONGODB 主機名

MONGODB_HOST = "127.0.0.1"

# MONGODB 端口號

MONGODB_PORT = 27017

# 數據庫名稱

MONGODB_DBNAME = "Douban"

# 存放數據的表名稱

MONGODB_SHEETNAME = "doubanmovies"

Scrapy 爬蟲完整案例-進階篇

第十二步: 編寫 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文件,運行爬蟲。

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

第十四步: 查看 MongoDB 數據庫

Scrapy 爬蟲完整案例-進階篇

顯示的只是一部分數據(Type "it" for more),如果想看完整的數據,可以通過 MongoDB 數據庫自帶的圖形化客戶端工具(MongoDB Compass Community)查看。

Scrapy 爬蟲完整案例-進階篇

1.2 進階篇案例二

案例:使用下載中間件(Downloader Middlewares)改寫爬取豆瓣電影top250案例

案例步驟:

第一步:創建爬蟲項目。

在 dos下切換到目錄

D:\\scrapy_project

Scrapy 爬蟲完整案例-進階篇

新建一個新的爬蟲項目:scrapy startproject douban2

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

第二步:創建爬蟲。

在 dos下切換到目錄。

D:\\scrapy_project\\douban2\\douban2\\spiders

用命令 scrapy genspider doubanmovie2 "movie.douban.com" 創建爬蟲。

Scrapy 爬蟲完整案例-進階篇

第三步: 開始前的準備工作。

(一)、在 scrapy.cfg 同級目錄下創建 pycharm 調試腳本 run.py,內容如下:

# -*- coding: utf-8 -*-

from scrapy import cmdline

cmdline.execute("scrapy crawl doubanmovie".split())

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

(二)、修改 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 文件。

Scrapy 爬蟲完整案例-進階篇

(三)不需要模擬登陸,settings.py 裡的 COOKIES_ENABLED ( Cookies中間件) 設置禁用狀態。

COOKIES_ENABLED = False

Scrapy 爬蟲完整案例-進階篇

備註:截圖使用的是案例一,步驟參考案例一。

第四步: 定義 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,

}

Scrapy 爬蟲完整案例-進階篇

第七步: 創建 MongoDB 數據庫"Douban"和存放爬蟲數據的表"doubanmovies"。

MongoDB中創建一個叫"Douban"的庫。

Scrapy 爬蟲完整案例-進階篇

MongoDB 創建數據庫的語法格式如下:

use DATABASE_NAME

如果數據庫不存在,則創建數據庫,否則切換到指定數據庫。

Scrapy 爬蟲完整案例-進階篇

備註:剛創建的數據庫 Douban 並不在數據庫的列表中, 要顯示它,我們需要向 Douban 數據庫插入一些數據或者創建表。

創建表:db.createCollection("doubanmovies")

語法格式:

db.createCollection(name, options)

Scrapy 爬蟲完整案例-進階篇

創建表完成,再去查 MongoDB 中的庫就顯示了 Douban 庫。

Scrapy 爬蟲完整案例-進階篇

查看錶:show collections

Scrapy 爬蟲完整案例-進階篇

第八步: 在settings.py文件裡配置 MongoDB 連接配置項

# MONGODB 主機名

MONGODB_HOST = "127.0.0.1"

# MONGODB 端口號

MONGODB_PORT = 27017

# 數據庫名稱

MONGODB_DBNAME = "Douban"

# 存放數據的表名稱

MONGODB_SHEETNAME = "doubanmovies"

Scrapy 爬蟲完整案例-進階篇

第九步: 編寫 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", "user_passwd" : " xiao@123"},

#{"ip_prot" :"121.42.140.113:16816", "user_passwd" : ""}

#{"ip_prot" :"121.42.140.113:16816", "user_passwd" : ""}

#{"ip_prot" :"121.42.140.113:16816", "user_passwd" : ""}

]

Scrapy 爬蟲完整案例-進階篇

【RandomUserAgent】:表示隨機的 Agent 。

【RandomProxy】:表示隨機的代理 。

代理可以去找免費的代理。

Scrapy 爬蟲完整案例-進階篇

也可以去購買私密代理。

快代理:https://www.kuaidaili.com

Scrapy 爬蟲完整案例-進階篇

備註:代理分免費代理和私密代理,免費代理的賬戶和密碼為空,私密代理有賬戶和密碼,這需要在下載中間鍵 middlewares.py 程序裡增加判斷"user_passwd"有沒有值,如果沒有值就不用。

第十一步: 編寫下載中間鍵 middlewares.py 文件。

import random,os,sys

import base64

path = os.path.dirname(os.path.abspath(__file__))

sys.path.append(path)

from douban2.settings import USER_AGENTS

from douban2.settings import PROXIES

# 隨機的User-Agent

class RandomUserAgent(object):

def process_request(self, request, spider):

useragent = random.choice(USER_AGENTS)

#設置請求頭的默認值

request.headers.setdefault("User-Agent", useragent)

class RandomProxy(object):

def process_request(self, request, spider):

proxy = random.choice(PROXIES)

# request.meta['proxy']表示當前請求使用的代理

if proxy['user_passwd'] is None:

# 沒有代理賬戶驗證的代理使用方式

request.meta['proxy'] = "http://" + proxy['ip_port']

else:

# 對賬戶密碼進行base64編碼轉換

base64_userpasswd = base64.b64encode(proxy['user_passwd'])

# 對應到代理服務器的信令格式裡

request.headers['Proxy-Authorization'] = 'Basic ' + base64_userpasswd

request.meta['proxy'] = "http://" + proxy['ip_port']

第十二步: 在 settings.py 文件裡設置延遲下載(防止訪問過於頻繁,設置為 2 秒 或更高)

DOWNLOAD_DELAY = 3

Scrapy 爬蟲完整案例-進階篇

第十三步: 執行run.py文件,運行爬蟲。

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇

第十四步: 查看 MongoDB 數據庫

Scrapy 爬蟲完整案例-進階篇

顯示的只是一部分數據(Type "it" for more),如果想看完整的數據,可以通過 MongoDB 數據庫自帶的圖形化客戶端工具(MongoDB Compass Community)查看。

Scrapy 爬蟲完整案例-進階篇

Scrapy 爬蟲完整案例-進階篇


分享到:


相關文章: