這樣的關(guān)鍵字能搜到很多很多文章米苹,可是,在我的實踐過程中砰琢,沒有一篇文章能夠待我穿過山和大海蘸嘶,也走過人山人海,相反陪汽,都是帶著我掉進(jìn)了坑训唱,陷進(jìn)了沼澤,掛在了樹上...
環(huán)境
python 叫做 Python3
掩缓,版本 v3.6.1
os 是 Mac os
scrapy 版本 v1.3.3
我有一個小目標(biāo)雪情,先扒下來幾百張圖再說
感謝douban,讓我一次一次又一次地爬...
目標(biāo)網(wǎng)頁: https://www.douban.com/doulist/1295618/
它看起來是這樣的
中國內(nèi)地電影票房總排行
而我們的目標(biāo)你辣,是將這些 下載下來電影海報巡通,順便記錄一下排行榜到csv文件
使用Scrapy創(chuàng)建一個項目
如果沒有安裝Scrapy
,可以參考我的另一篇文章安裝scrapy舍哄。我們這里使用命令生成一個腳手架
scrapy startproject douban
生成后的項目結(jié)構(gòu)如下(根目錄):
├── scrapy.cfg
└── scrapyspider # 項目目錄
├── items.py # 模型文件宴凉,定義要抓取的對象,后期修改
├── middlewares.py
├── pipelines.py # 以管道方式處理模型表悬,后期修改
├── settings.py # 項目配置文件弥锄,后期修改
└── spiders # 爬蟲文件夾
└── douban_spider.py # 后期新增的爬蟲文件
需要注意:
- 由于使用我們的管道繼承了scrapy的圖片管道,所以項目依賴
Pillow
的庫蟆沫,使用
python3 -m pip install pillow
來安裝PIL的依賴
- 運行爬蟲時籽暇,需要切換到項目根目錄下,然后
scrapy crawl xxx
其中xxx是爬蟲的名字(注:不是文件名哦饭庞,是爬蟲的name屬性)
文件如下
setting.py
import os
BOT_NAME = 'douban'
SPIDER_MODULES = ['douban.spiders']
NEWSPIDER_MODULE = 'douban.spiders'
DOWNLOADER_DEBUG = True #這5行不是必須的戒悠,只是為了調(diào)試方便
CONCURRENT_REQUESTS = 200
AUTOTHROTTLE_DEBUG = True
AUTOTHROTTLE_ENABLED= True
DEPTH_STATS_VERBOSE = True # 5行到這里
CUR_DIR = os.path.dirname(os.path.realpath(__file__))
IMAGES_STORE = os.path.join(CUR_DIR, '..', 'images')
ITEM_PIPELINES = {
'douban.pipelines.DoubanPicPipelines': 1
}
COOKIE_ENABLE = False # 建議有,不要記著我的臉舟山,不要cookie
DOWNLOAD_DELAY = 0.5 # 建議有绸狐,步子不要太大卤恳,否則容易扯著蛋
ROBOTSTXT_OBEY = False # 必須有,否則你的爬蟲會按照robot.txt規(guī)則來決定能否爬當(dāng)前內(nèi)容
ITEM_PIPELINES
屬性描述了管道流寒矿,key是管道類的類名突琳,value是一個數(shù)字,用來描述任務(wù)優(yōu)先級符相,1就是最早執(zhí)行拆融,數(shù)字越大,執(zhí)行順序就越晚
pipelines.py
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
from scrapy import Request
class DoubanPicPipelines(ImagesPipeline):
def get_media_requests(self,item,info):
for image_url in item['image_urls']:
yield Request(image_url)
def item_completed(self,results,item,info):
image_paths=[x['path'] for ok,x in results if ok] # 這里的path是item自動加上的
if not image_paths:
raise DropItem('圖片未下載好 %s'%image_paths)
items.py
import scrapy
class DoubanItem(scrapy.Item):
ranking = scrapy.Field()
# movie's name
movie_name = scrapy.Field()
# score
score = scrapy.Field()
# comment count
score_num = scrapy.Field()
# image_urls
image_urls = scrapy.Field()
# image name
images = scrapy.Field()
spiders/douban_spider.py
from scrapy.spiders import Spider
from scrapy.http import Request
from douban.items import DoubanItem
import re
class DoubanMovieSpider(Spider):
name = 'movie' # 這個名字決定了使用scrapy crawl movie來啟動爬蟲
headers = { # 沒有UA主巍,網(wǎng)站不待見你
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:54.0) Gecko/20100101 Firefox/54.0'
}
def start_requests(self):
url = 'https://www.douban.com/doulist/1295618/'
yield Request(url, headers=self.headers)
def parse(self, response):
item = DoubanItem()
movies = response.xpath('//div[@class="doulist-item"]/div')
for movie in movies:
item['ranking'] = movie.xpath(
'.//span[@class="pos"]/text()').extract()[0]
item['movie_name'] = movie.xpath(
'.//div[@class="title"]/a/text()').extract()[0]
score = movie.xpath('.//span[@class="rating_nums"]/text()').extract()
if score:
score = score[0]
else:
score = 'N/A'
item['score'] = score
score_num = movie.xpath('.//div[@class="rating"]/span[3]').re(r'(\d+)')
if score_num:
score_num = score_num[0]
else:
score_num = 'N/A'
item['score_num'] = score_num
image_urls = movie.xpath('.//div[@class="post"]/a/img/@src').extract()
item['image_urls'] = image_urls
item['images'] = movie.xpath(
'.//div[@class="post"]/a/img/@src').re(r'[^/]*.[jpg|png|gif|webp]$')
yield item
# 處理分頁
next_url = response.xpath('//span[@class="next"]/a/@href').extract()
if next_url:
yield Request(next_url[0], headers = self.headers)
運行爬蟲冠息,
scrapy crawl movie -o movies.cvs
稍等片刻,就能夠看到生成出來的cvs文件了孕索,使用wps打開,能夠看到漂亮的中文(office貌似是亂碼)
cvs文件躏碳,可以很方便排序
下載下來的海報