Scrapy:根據目錄來下載github上的檔案

ditclear發表於2019-03-01

寫在前面

最近在學習Python的語法,刷刷LeetCode什麼的。熟悉之後,就想著寫一個爬蟲實際運用一下。

如何入門 Python 爬蟲? - 高野良的回答 - 知乎

知乎了一下,然後看了scrapy的文件 ,就開始動手了。

那麼爬什麼呢❓

當時就想著寫一個根據目錄來下載github倉庫檔案的spider。因為以前下載github倉庫的時候要麼只能根據git地址clone整個repo,要麼只能通過octoTree或者insightio下載單個檔案,然而經常會有需要下載單個或者多個目錄的情況,所以就想著寫一個根據目錄來下載github上檔案的爬蟲。

開始

要開始,當然是推薦看官方的入門教程了。

這裡簡單描述下步驟:

##1.建立專案
scrapy startproject scrapy_github_dir
##2.建立爬蟲
scrapy genspider app github.com
##3.寫邏輯或者進行設定等等
##4.執行爬蟲,爬取路徑是github上的目錄或者檔案
scrapy crawl app -a urls = https://github.com/ditclear/BindingListAdapter/tree/917e254f527d101e3f583c38739a61f3bcffbc11/library-kotlin
複製程式碼

主要的程式碼都在app.py裡,當執行scrapy genspider app github.com時會主動幫你生成它

import scrapy
from ..items import ScrapyGithubDirItem

class AppSpider(scrapy.Spider):
    name = 'app'
    allowed_domains = ['github.com']
    content_domains = 'https://github.com/'
    start_urls = []

    def __init__(self, urls=None, *args, **kwargs):
        super(AppSpider, self).__init__(*args, **kwargs)
        self.start_urls = urls.split(',')
	//執行scrapy crawl xx 後,處理response
    def parse(self, response):
        raw_url = response.css('a#raw-url').xpath('@href').extract_first()
        if raw_url:
                href = self.content_domains+raw_url
                print("scrapy from href --> ", href)
                yield scrapy.Request(href, callback=self.parse_link)
        else:
            for link in response.selector.xpath('//a[@class="js-navigation-open"]/@href').extract()[1:]:
                href = self.content_domains+link
                yield scrapy.Request(href, callback=self.parse)

    def parse_link(self, response):
        responseStr = str(response).strip()
        url = responseStr.strip()[5:len(responseStr)-1]
        print('download from url --> ', url)
        item = ScrapyGithubDirItem()
        item['file_urls'] = [url]
        return item

複製程式碼

當執行scrapy crawl xx 後,會在parse(self, response)方法處理response。

處理response,簡單理解來就是通過css選擇器和xpath來找到你想要的內容,比如text/img/href等等,獲取到想要的內容後,儲存到檔案、資料庫,期間摻雜著一些scarpy的配置。

通過分析網頁原始檔:

raw-rul

可以看到單個檔案的下載連結在id為raw-url的a標籤中,所以我們需要找到這個標籤然後獲取到想要的連結。

raw_url = response.css('a#raw-url').xpath('@href').extract()
複製程式碼

這裡的意思是通過css選擇器找到id為raw-url的a標籤,然後獲取到a標籤的href引數,最後提取出來以列表的形式返回。

如果沒有返回那麼則表示當前request的url不是具體的某個檔案,而是一個目錄。

如果當前url是目錄

分析一下目錄的response的結構,通過css選擇器和xpath繼續找到其下一級的檔案

js-navigation-open

同樣的,找到這個地址

response.selector.xpath('//a[@class="js-navigation-open"]/@href').extract()
複製程式碼

需要注意的是返回的列表中,第一個索引的值指向的是上一級目錄,所以需要將其排除掉。接著遞迴呼叫當前的parse方法,直到爬取到檔案為止。

if raw_url:
	//爬取具體的檔案
    yield scrapy.Request(href, callback=self.parse_link)
else:
    //如果是目錄,遞迴直到爬取到檔案為止
    for link in response.selector.xpath('//a[@class="js-navigation-open"]/@href').extract()[1:]:
    	yield scrapy.Request(href, callback=self.parse)
複製程式碼

程式碼不多,順利的話半天就能成功。

scrapy

Scrapy:根據目錄來下載github上的檔案

寫在最後

回顧一下,能發現沒怎麼就已經寫好了。而爬蟲簡單看來就是通過css選擇器、xpath或者正則找到需要的資料,然後進行想要的處理,期間夾雜著遞迴的邏輯和演算法,當然這只是初見scrapy,不過已經能發現Python以及Scrapy的強大了。

github地址:github.com/ditclear/sc…

參考資料:

scrapy-chs.readthedocs.io/zh_CN/1.0/t…

相關文章