最近在學習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
經過分析網頁源文件:
能夠看到單個文件的下載連接在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繼續找到其下一級的文件
一樣的,找到這個地址
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)
複製代碼
代碼很少,順利的話半天就能成功。
回顧一下,能發現沒怎麼就已經寫好了。而爬蟲簡單看來就是經過css選擇器、xpath或者正則找到須要的數據,而後進行想要的處理,期間夾雜着遞歸的邏輯和算法,固然這只是初見scrapy,不過已經能發現Python以及Scrapy的強大了。
github地址:github.com/ditclear/sc…