Scrapy:根據目錄來下載github上的文件

寫在前面

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

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

知乎了一下,而後看了scrapy的文檔 ,就開始動手了。python

那麼爬什麼呢❓git

當時就想着寫一個根據目錄來下載github倉庫文件的spider。由於之前下載github倉庫的時候要麼只能根據git地址clone整個repo,要麼只能經過octoTree或者insightio下載單個文件,然而常常會有須要下載單個或者多個目錄的狀況,因此就想着寫一個根據目錄來下載github上文件的爬蟲。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時會主動幫你生成它bash

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。app

處理response,簡單理解來就是經過css選擇器和xpath來找到你想要的內容,好比text/img/href等等,獲取到想要的內容後,保存到文件、數據庫,期間摻雜着一些scarpy的配置。dom

經過分析網頁源文件:

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

寫在最後

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

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

參考資料:

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

相關文章
相關標籤/搜索