1.在items.py中定義字段,這些字段用來(lái)保存數(shù)據(jù)鲫忍,方便后續(xù)的操作
import scrapy
class MovieItem(scrapy.Item):
rank = scrapy.Field() # 排名
title = scrapy.Field() # 名稱(chēng)
score = scrapy.Field() # 評(píng)分
2.修改settings.py對(duì)項(xiàng)目進(jìn)行配置
- 設(shè)置用戶(hù)代理,模擬瀏覽器訪問(wèn)頁(yè)面
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' \
'Chrome/66.0.3359.181 Safari/537.36'
- 是否遵循robots協(xié)議。
如果沒(méi)有配置USER_AGENT,需要把ROBOTSTXT_OBEY的值改為False
ROBOTSTXT_OBEY = True
- 指定請(qǐng)求數(shù)目颠蕴,相當(dāng)于線(xiàn)程數(shù)量,盡可能用較小的數(shù)助析。
CONCURRENT_REQUESTS = 1
- 配置DOWNLOAD_DELAY
DOWNLOAD_DELAY = 5
- 緩存頁(yè)面
HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_DIR = 'httpcache'
HTTPCACHE_IGNORE_HTTP_CODES = []
HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
如果想要指定代理用戶(hù)犀被,需要做如下操作:
- 在settings.py中配置DOWNLOADER_MIDDLEWARES
DOWNLOADER_MIDDLEWARES = {
'douban.middlewares.DoubanDownloaderMiddleware': 543,
}
- 在middlewears.py中配置
找到DoubanDownloaderMiddleware類(lèi)的process_request函數(shù),修改函數(shù)為如下內(nèi)容
class DoubanDownloaderMiddleware(object):
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
request.meta['proxy'] = 'http://ip:port'
3.編寫(xiě)我們的spider
rules中的LinkExtractor方法會(huì)自動(dòng)去頁(yè)面中搜索和rules中規(guī)則相匹配的url外冀,callback指定調(diào)用的函數(shù)寡键。
# -*- coding: utf-8 -*-
import scrapy
from douban2.items import MovieItem
class MovieSpider(scrapy.Spider):
name = 'movie'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250']
# parse 是回調(diào)函數(shù)
def parse(self, response):
# 獲取首頁(yè)最下面的頁(yè)面跳轉(zhuǎn)鏈接
# 由于需要獲取每個(gè)頁(yè)面中的電影詳情頁(yè)
# 所以對(duì)于獲取 的url ,需要指定回調(diào)函數(shù) parse()
for a in response.xpath('//*[@id="content"]/div/div[1]/div[2]/a'):
url = response.urljoin(a.xpath('@href').extract_first())
yield scrapy.Request(url=url, callback=self.parse)
# 獲取電影詳情頁(yè)面鏈接
# 由于需要通過(guò)電影詳情頁(yè)獲取每部電影的信息
# 所以對(duì)于此處獲取的url雪隧,需要指定回調(diào)函數(shù) parse_item()
for li in response.xpath('//*[@id="content"]/div/div[1]/ol/li'):
url = li.xpath('div/div[2]/div[1]/a/@href').extract_first()
yield scrapy.Request(url=url, callback=self.parse_item)
def parse_item(self, response):
item = MovieItem()
item['rank'] = response.xpath('//*[@id="content"]/div[1]/span[1]/text()').extract_first()
item['title'] = response.xpath('//*[@id="content"]/h1/span[1]/text()').extract_first()
item['score'] = response.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/strong/text()').extract_first()
return item
4.啟動(dòng)shell西轩,看spider是否能成功請(qǐng)求網(wǎng)頁(yè):
scrapy shell "https://movie.douban.com/top250"
注意:網(wǎng)頁(yè)鏈接必須用雙引號(hào),如果用單引號(hào)會(huì)發(fā)生如下錯(cuò)誤:
如果看到下面的結(jié)果膀跌,則表示請(qǐng)求成功遭商。
5.運(yùn)行爬蟲(chóng),抓取數(shù)據(jù)
由于此處還沒(méi)有把抓取到的有效內(nèi)容做持久化處理捅伤,所有可以把內(nèi)容重定向到一個(gè)文件中,便于我們查看巫玻。要實(shí)現(xiàn)這樣的效果丛忆,只需要在命令后面加上 -o <filename>祠汇,此處我把結(jié)果存儲(chǔ)在result.json文件中。
scrapy crawl movie -o result.json
6.執(zhí)行結(jié)果:
項(xiàng)目文件夾中生成了一個(gè)result.json文件熄诡,里面保存了抓取的全部數(shù)據(jù)信息可很。
通過(guò)菜鳥(niǎo)工具JSON在線(xiàn)解析幫助我們更好的查看數(shù)據(jù)。
總共抓取到了246條信息凰浮,網(wǎng)頁(yè)中應(yīng)該是有250個(gè)電影信息我抠,經(jīng)過(guò)建廠,發(fā)現(xiàn)網(wǎng)頁(yè)中存在一些死鏈接袜茧,說(shuō)明我們的spider成功抓取到了我們需要的所有信息菜拓。