最近在学习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…