Python日記:基於Scrapy的爬蟲實現,pythonscrapy

來源:互聯網
上載者:User

Python日記:基於Scrapy的爬蟲實現,pythonscrapy

安裝 pywin32 和python版本一致 

地址 https://sourceforge.net/projects/pywin32/files/pywin32/Build%20221/
安裝過程中提示找不到Python2.7
解決方案:http://blog.csdn.net/pppii/article/details/48679403

安裝Scrapy 使用pip

1、使用命令列建立爬蟲項目
scrapy startproject myspider # cmd進入指定檔案夾後建立一個名為 myspider的爬蟲

2、啟動pyCharm
開啟項目 myspider ,在檔案夾spiders下建立MySprider.py檔案
添加我的爬蟲 class Channel9Spider(scrapy.Spider):
name 表示爬蟲的名稱 屬於唯一屬性
allowed_domins=[] 爬蟲允許的網域
start_urls=[] 爬蟲開始的頁面
def parse(self,response): 訪問地址後調用的方法
def details_parse(self,response): 處理詳情頁面的方法

MySprider.py遇到的問題:
1、windows命令提示字元中列印爬取的檔案名稱報錯
原因:是命令列字元集和網頁字元集不一致
處理方法:print item["title"].encode("gbk","ignore")
2、回調方法報錯
原因:PyScrapy預設給回調加了個括弧
處理方法:去掉回調方法後的括弧,需要傳參使用Request(url=.. , meta={'name':'yancl',....},calback=self.details_parse,dont_filter=True)
3、提示訪問被拒絕
原因:1、robots 協議問題 2、由於設定了允許爬取的域
處理方法:1、修改settings.py 設定ROBOTSTXT_OBEY = True
2、調用Request方法設定dont_filter=True

開啟 items.py
添加在處理頁面後要傳遞給pipeline的item資料對象
用到了下載所以添加 file_urls,files,file_paths

開啟 pipeline.py
1、添加一個繼承FilesPipeline檔案下載管道的實現方法 MyFilesPipeline
2、添加一個記錄檔案方法 JsonWithEncodingPipeline

開啟settings.py
1、啟用我的Item Pipeline組建。我打算下載一個視頻就記錄一條對應的Json資訊
2、添加視頻下載儲存檔案的路徑


再次啟動爬蟲 scrapy crawl myspider
遇到的問題:
1、下載檔案過大
2、連線逾時
3、檔案下載的路徑問題,預設添加full的檔案夾
4、檔案名稱問題

對於問題1、2、3 修改settings
DOWNLOAD_MAXSIZE = 325674803 #位元組
DOWNLOAD_WARNSIZE = 325674803 #位元組
DOWNLOAD_TIMEOUT = 30 * 60 #單位秒
FILES_STORE = "F:\\mp4files" #直接使用絕對路徑
對於問題3,修改MyFilesPipeline方法 重寫file_path方法

再次啟動爬蟲運行正常,但是還有2個小問題,1、有一個檔案自動添加了檔案夾 2、有幾個檔案沒有尾碼大小為0KB
根據日誌分析是檔案名稱導致了 檔案名稱中不能有:/ 等特殊字元

MySpider.py

import scrapyfrom mydemo.items import MydemoItemfrom scrapy.http import Requestfrom scrapy.selector import Selectordownload_domain = "https://channel9.msdn.com"class Channel9Spider(scrapy.Spider):    name = "myspider"    allowed_domains = [".msdn.com"]    start_urls = [        "https://channel9.msdn.com/Events/Ignite/Microsoft-Ignite-China-2016?sort=status&direction=desc"    ]    def parse(self,response):        sale = Selector(response)        for a in sale.xpath("//h3"):            title = a.xpath("a/text()").extract()[0]            line = a.xpath("a/@href").extract()[0]            fileurl = download_domain + line            yield Request(url=fileurl,meta={'title':title},callback=self.details_parse,dont_filter=True)        next_page = sale.xpath("//a[@rel='next']/@href").extract()        if next_page:            pagepath =  download_domain+next_page[0]            yield Request(url=pagepath,callback=self.parse,dont_filter=True)    def details_parse(self,response):        sale = Selector(response)        item = MydemoItem()        item["title"] = response.meta['title']        fileurl = sale.xpath("//*[@id='format']/option/@value").extract()[0]        item["file_urls"] = [fileurl]        yield item

items.py

class MydemoItem(scrapy.Item):    # define the fields for your item here like:    # name = scrapy.Field()    title = scrapy.Field()    link = scrapy.Field()    content = scrapy.Field()    file_urls = scrapy.Field()    files = scrapy.Field()    file_paths = scrapy.Field()    pass

pipelines.py

# -*- coding: utf-8 -*-# Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.htmlimport scrapyimport codecsimport jsonimport timefrom scrapy.pipelines.files import FilesPipelinefrom scrapy.exceptions import DropItemclass MydemoPipeline(object):    def process_item(self, item, spider):        return itemclass JsonWithEncodingPipeline(object):    def __init__(self):        self.file = codecs.open('file.json','w',encoding='utf-8')    def process_item(self,item,spider):        timeSatamp = time.time()        timeTuple = time.localtime(timeSatamp)        curTime = time.strftime("%Y-%m-%d %H:%M:%S",timeTuple)        line = "["+curTime+"] "+json.dumps(dict(item),ensure_ascii=False)+"\n"        self.file.write(line)        return item    def spider_closed(self,spider):        self.file.close()class MyFilesPipeline(FilesPipeline):    def get_media_requests(self,item,info):        for file_url in item['file_urls']:            yield scrapy.Request(file_url,meta={'title':item['title']})    def item_completed(self, results, item, info):        file_paths = [x['path'] for ok, x in results if ok]        if not file_paths:            raise DropItem("Item contains no Files")        item["file_paths"] = file_paths        return item    def file_path(self,request,response=None,info=None):        title = request.meta['title']        file_guid = title + '.'+request.url.split('/')[-1].split('.')[-1]        filename = u'{0}'.format(file_guid)        return filename

settings.py 

 

產生的日誌如下:

爬取的檔案:

  

 

 

 

 



 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.