scrapy爬取豆瓣電影
這兩天學習了下scrapy,並試著用它爬取了大家都扎堆爬的豆瓣排名前250的電影,中間提升了自己對scrapy的認識,並踩了一些坑總結一下。(以下內容基於Python3.5;scrapy1.3.3下)
1.定義所需爬取元素的model
items.py
import scrapy
class DoubanscrapyItem(scrapy.Item):
url = scrapy.Field()
rank = scrapy.Field()
movie_name = scrapy.Field()
comment = scrapy.Field()
price = scrapy.Field ()
爬取元素並不是必須宣告一個model,也可以直接在爬蟲程式碼中,將爬取的元素直接通過這種方式來展現
yield {
url: .....,
movie_name: .....
}
省略部分是爬取對應元素的規則
根據官方文件介紹,Item是儲存結構資料的地方,Scrapy可以將解析結果以字典形式返回,但是Python中字典缺少結構,在大型爬蟲系統中很不方便,Item提供了類字典的API,並且可以很方便的宣告欄位,很多Scrapy元件可以利用Item的其他資訊。後面也可以方便pipelines對爬到的資料進行處理
2.爬蟲實現程式碼
douban_spider.py
from scrapy import Request, Spider
from doubanScrapy.items import DoubanscrapyItem
class DoubanScrapy(Spider):
"""docstring for DoubanScrapy"""
name = 'douban'
# 爬蟲起始url
start_urls = ["https://movie.douban.com/top250"]
def start_request(self):
yield Request(self.start_urls, callback = self.parse)
def parse(self, response):
for msg in response.xpath('//div[@class="item"]'):
item = DoubanscrapyItem()
item['url'] = msg.xpath('div[@class="pic"]/a/@href').extract()[0]
item['rank'] = msg.xpath('div[@class="pic"]/em/text()').extract()[0]
item['movie_name'] = msg.xpath('div[@class="pic"]/a/img/@alt').extract()[0]
item['price'] = msg.xpath('div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()').extract()[0]
comment = msg.xpath('div[@class="info"]/div[@class="bd"]/p[@class="quote"]/span/text()').extract()
# 爬取過程中,有些沒有直接的評論,做些處理
if comment:
item['comment'] = comment[0]
yield item
#獲取當前url的下一頁連結
next_page = response.xpath('//span[@class="next"]/a/@href').extract_first()
if next_page:
request_url = response.urljoin(next_page)
print (request_url)
yield Request(request_url, callback = self.parse)
這一塊主要是爬取頁面,並將對應元素傳到定義好的資料字典中。
我這塊頁面元素的獲取是用的xpath,也可以使用css selector獲取,官方介紹
好了,現在通過scrapy crawl douban -o douban_movie.json
命令執行程式,並將爬到的資料存在指定的檔案裡,可以發現,出了問題
爬蟲被豆瓣給屏了,主要原因是豆瓣的設了一個路障,開啟開發者工具,我們可以看到,正常的通過瀏覽器訪問一個頁面的請求頭的User-Agent是如下設定:
所以現在只需要修改下資料夾下的settings.py檔案中的USER_AGENT
重新賦值為Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
就ok了,檢視下圖:
3.資料的處理
pipelines.py
這個檔案主要是對抓取資料進行進一步的處理,如存資料庫等等,下面是簡單的將電影連結寫入一個檔案,當然通過上面說的命令列方式也是可以的。
首先需要在settings.py 修改一處地方
ITEM_PIPELINES = {
'doubanScrapy.pipelines.DoubanscrapyPipeline': 300,
}
這幾句在配置檔案中預設是註釋掉的,現在去掉註釋就行啦。
class DoubanscrapyPipeline(object):
def process_item(self, item, spider):
with open('D:/workspace4/doubanScrapy/douban_movie.json', 'at') as f:
f.write('url:' + item['url'] + '\n')
將url寫入指定檔案中,執行scrapy crawl douban
結果如下: