天天看點

用Scrapy爬蟲下載下傳圖檔(豆瓣電影圖檔)

用Scrapy爬蟲的安裝和入門教程,這裡有,這篇連結的部落格也是我這篇部落格的基礎。

其實我完全可以直接在上面那篇部落格中的代碼中直接加入我要下載下傳圖檔的部分代碼的,但是由于上述部落格中的代碼已運作,已爬到快九千的電影詳情資料,不忍重新爬一次,是以爬豆瓣電影圖檔的爬蟲重新寫一遍。

前言:我的需求是根據已有電影名在豆瓣中搜尋電影,然後獲得電影的連結,繼續爬蟲,獲得電影的圖檔。

上述連結的部落格的需求我在這裡也順帶列一下,不關心的直接忽略之:我要爬的是豆瓣的資料,我有了很多電影的名字,但是我需要電影的詳情,我用了一下豆瓣電影的網站,發現當我在搜尋框裡輸入“Last Days in Vietnam”時url會變成http://movie.douban.com/subject_search?search_text=Last+Days+in+Vietnam&cat=1002 然後我就試着直接輸入http://movie.douban.com/subject_search?search_text=Last+Days+in+Vietnam這個url,搜尋結果是一樣的,很顯然這就是get方式,這樣我們就找到了規律:http://movie.douban.com/subject_search?search_text=後面加上我們的電影名字并用加号分割就行了。我們的電影名字(大量的電影名字)是存在movie_name.txt這個檔案中裡面的(一行一個電影名字)。我們可以先用python腳本(shell腳本也行)将電影名之間的空格處理為+,也可以在爬蟲中讀取電影名後進行一次replace處理(我是先處理成+的)。爬蟲讀取電影名字檔案,然後建構url,然後就根據得到的網頁找到搜尋到的第一個電影的url(其實第一個電影未必一定是我們要的,但是這種情況是少數,我們暫時不理會它),得到第一個電影的url後,再繼續爬,這次爬到的頁面就含有我們想要的電影資訊,需要使用XPath來獲得html檔案中元素節點,最後将獲得的資訊存到TutorialItem中,通過pipelines寫入到data.dat檔案中。

電影圖檔下載下傳核心:

用Scrapy爬蟲下載下傳圖檔(豆瓣電影圖檔)

其中urllib.urlretrieve就是核心,到這裡讀者應該就知道怎麼下載下傳圖檔了(參考文章:http://www.tuicool.com/articles/7JVvaa),而且可以命名為我們自己想要的名字。關于urllib的urlretrieve方法的詳細解釋見這裡,當然,也可以去看python官方文檔。

還有一種辦法來處理圖檔下載下傳:Scrapy的ImagesPipeline,這裡有篇教程。

沒興趣的就不要繼續往下面閱讀了,以免浪費大家的時間。下面記錄的是我爬圖檔的所有代碼。

————————————————————————————————————————————————————————————————————

1、item檔案:

1 #coding=utf-8
 2 # Define here the models for your scraped items
 3 #
 4 # See documentation in:
 5 # http://doc.scrapy.org/topics/items.html
 6 
 7 
 8 from scrapy.item import Item, Field
 9 
10 class TutorialItem(Item):
11     # define the fields for your item here like:
12     # name = Field()
13         #movie_detail = Field()
14         movie_id = Field()
15     movie_picture = Field()      

items.py

2、pilelines檔案:

1 # Define your item pipelines here
 2 #
 3 # Don't forget to add your pipeline to the ITEM_PIPELINES setting
 4 # See: http://doc.scrapy.org/topics/item-pipeline.html
 5 import json
 6 import codecs
 7 
 8 class TutorialPipeline(object):
 9     def __init__(self):
10         self.file = codecs.open('pic.dat',mode='a+',encoding='utf-8')
11 
12         def process_item(self, item, spider):
13             line = json.dumps(dict(item)) + '\n'
14             self.file.write(line.decode("unicode_escape"))
15             
16             return item      

pipelines.py

【mode='a+'】表明我對存儲圖檔url的檔案的讀寫是以追加的方式寫的。

3、spiders檔案:

#coding=utf-8
import sys
reload(sys)
#python預設環境編碼時ascii
sys.setdefaultencoding("utf-8")
from scrapy.spider import BaseSpider
from scrapy.http import Request
from scrapy.selector import HtmlXPathSelector
from tutorial.items import TutorialItem
import re
import urllib

class DoubanSpider(BaseSpider):
    name = "douban"
    allowed_domains = ["movie.douban.com"]
    start_urls = []

    def start_requests(self):
        file_object = open('movie_name.txt','r')

        try:
            url_head = "http://movie.douban.com/subject_search?search_text="
            for line in file_object:
                self.start_urls.append(url_head + line)
            
            for url in self.start_urls:
                yield self.make_requests_from_url(url)
        finally:
            file_object.close()
            #years_object.close()

    def parse(self, response):
        #open("test.html",'wb').write(response.body)
        hxs = HtmlXPathSelector(response)
        movie_link = hxs.select('//*[@id="content"]/div/div[1]/div[2]/table[1]/tr/td[1]/a/@href').extract()

        if movie_link:
            yield Request(movie_link[0],callback=self.parse_item)
        
        
    def parse_item(self,response):
        hxs = HtmlXPathSelector(response)
        movie_picture = hxs.select('//*[@id="mainpic"]/a/img/@src').extract()
        item = TutorialItem()

        item['movie_picture'] = ''.join(movie_picture).strip()

        #用來給爬到的圖檔指令的,這個檔案裡隻有一行資料,因為我會在我的main.py檔案中調用scrapy爬蟲,會在main.py中不斷更新這個檔案
        movie_id_file = open('movie_id.txt','r')
        try:
            for line in movie_id_file:
                item['movie_id'] = line.strip()
                if movie_picture:
                    urllib.urlretrieve(movie_picture[0].strip(),'pictures\\' + line.strip() + '.jpg')
        finally:
            movie_id_file.close()


        yield item      

douban_spider.py

4、main檔案:這個檔案是用來控制Scrapy來爬蟲的

#coding=utf-8
import sys
reload(sys)
#python預設環境編碼時ascii
sys.setdefaultencoding("utf-8")

import os

#os.system(r"scrapy crawl douban")
#讀取電影資料
movies_info = open('movies.sql','r')
try:
    for line in movies_info:
        #将每條電影資料裡面的需要的資料提取出來
        movie_infos = line.split(',',4)

        movie_id = movie_infos[1]
        movie_title = movie_infos[2]
        #print movie_id + ":" + movie_title

        write_name = movie_title.replace('_','+')
        write_name = write_name.replace('\'','')
        #print "name is :" + write_name
        #把電影名寫到中間檔案中去,讓爬蟲讀取
        movie_name_file = open('movie_name.txt','w')
        try:
            movie_name_file.write(write_name)
        finally:
            movie_name_file.close()
        #把電影id寫到中間檔案中去,讓爬蟲讀取
        movie_id_file = open('movie_id.txt','w')
        try:
            movie_id_file.write(movie_id)
        finally:
            movie_id_file.close()

        #該爬蟲程式會從movie_name中讀取電影名來爬蟲
        os.system(r"scrapy crawl douban")

finally:
    movies_info.close()      

main.py

main.py讀取的movies.sql的格式我截圖一下:

用Scrapy爬蟲下載下傳圖檔(豆瓣電影圖檔)

上述的moive_name是用來在豆瓣中進行電影搜尋的,moive_id是給圖檔來命名的,我把這兩個東西分别寫到了兩個不同的檔案中,供spider來讀取。

用Scrapy爬蟲下載下傳圖檔(豆瓣電影圖檔)

在douban_spider.py中對上述兩個檔案進行讀:

用Scrapy爬蟲下載下傳圖檔(豆瓣電影圖檔)
用Scrapy爬蟲下載下傳圖檔(豆瓣電影圖檔)

然後在DOS中切換到tutorial目錄下輸入python main.py就可以爬啦……

好了,可以爬取圖檔了,給大家看看結果:

用Scrapy爬蟲下載下傳圖檔(豆瓣電影圖檔)

寫寫部落格記錄自己實踐過程,也希望對需要者有用。

轉載于:https://www.cnblogs.com/Shirlies/p/4537931.html