Shirlies
宁静专注认真的程序媛~

用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就可以爬啦……

 

好了,可以爬取图片了,给大家看看结果:

写写博客记录自己实践过程,也希望对需要者有用。

 

posted on 2015-05-29 10:45  Shirlies  阅读(10721)  评论(3编辑  收藏  举报