用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文件中。

電影圖片下載核心:

其中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的格式我截圖一下:

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

在douban_spider.py中對上述兩個文件進行讀:

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

 

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM