Python 學(xué)習(xí)網(wǎng)絡(luò)爬蟲(chóng)篇

Python的創(chuàng)世人是吉多·范羅蘇姆橙依。1989年圣誕節(jié)期間眨八,吉多為了在阿姆斯特丹打發(fā)時(shí)間钞它,決心開(kāi)發(fā)一個(gè)新的腳本解釋程序作為ABC語(yǔ)言的一種繼承坡垫。ABC是由吉多參加設(shè)計(jì)的一種教學(xué)語(yǔ)言彭沼。就吉多本人看來(lái)缔逛,ABC這種語(yǔ)言非常優(yōu)美和強(qiáng)大,是專門(mén)為非專業(yè)程序員設(shè)計(jì)的姓惑。但是ABC語(yǔ)言并沒(méi)有成功褐奴,究其原因,吉多認(rèn)為是非開(kāi)放造成的于毙。吉多決心在Python中避免這一錯(cuò)誤敦冬,并獲取了非常好的效果,完美結(jié)合了C和其他一些語(yǔ)言唯沮,就這樣脖旱,Python在吉多手中誕生了。

Python 特點(diǎn)

  1. 優(yōu)點(diǎn):簡(jiǎn)單介蛉、易學(xué)萌庆、速度快、免費(fèi)币旧、開(kāi)源踊兜、高層語(yǔ)言、可移植佳恬、解釋性捏境、面向?qū)ο蟆⒖蓴U(kuò)展毁葱、可嵌入垫言、豐富的庫(kù)、規(guī)范的代碼
  2. 缺點(diǎn):?jiǎn)涡姓Z(yǔ)句倾剿、運(yùn)行速度慢筷频、獨(dú)特的語(yǔ)法(通過(guò)縮進(jìn)區(qū)分語(yǔ)句關(guān)系)

Python應(yīng)用

Python應(yīng)用非常廣泛,如系統(tǒng)編程前痘、圖形處理凛捏、數(shù)學(xué)處理、文本處理芹缔、數(shù)據(jù)庫(kù)編程坯癣、網(wǎng)絡(luò)編程、Web編程最欠、多媒體應(yīng)用示罗、Pymo引擎惩猫、黑客編程、網(wǎng)絡(luò)爬蟲(chóng)等蚜点,本篇文章就來(lái)學(xué)習(xí)一下Python的網(wǎng)絡(luò)爬蟲(chóng)

Python爬蟲(chóng)框架

python爬蟲(chóng)框架有很多轧房,如Scrapy、PySpider绍绘、Crawley奶镶、Portia、Newspaper陪拘、Beautiful Soup实辑、Grab、Cola等藻丢,這么多框架不用學(xué)很多,學(xué)一個(gè)就可以摄乒,下面我們就來(lái)先學(xué)下一下比較熱門(mén)的Scrapy框架

Scrapy框架

  • 簡(jiǎn)介

Scrapy是一個(gè)用于以一種快速悠反、簡(jiǎn)單、可擴(kuò)展的方式從網(wǎng)站中提取所需要數(shù)據(jù)的開(kāi)源框架馍佑。用途廣泛斋否,可以用于數(shù)據(jù)挖掘、監(jiān)測(cè)和自動(dòng)化測(cè)試拭荤。Scrapy吸引人的地方在于它是一個(gè)框架茵臭,任何人都可以根據(jù)需求方便的修改。它也提供了多種類(lèi)型爬蟲(chóng)的基類(lèi)舅世,如BaseSpider旦委、sitema等

  • 相關(guān)學(xué)習(xí)資料網(wǎng)址

scrapy官網(wǎng):https://scrapy.org/
scrapy文檔:https://docs.scrapy.org/en/latest/
github地址:https://github.com/scrapy/scrapy/
css選擇器:http://www.w3school.com.cn/cssref/css_selectors.asp
xpath選擇器:http://www.w3school.com.cn/xpath/index.asp

  • 配置環(huán)境

首先需要配置Python3的環(huán)境,mac配置非常簡(jiǎn)單雏亚,只需要在終端執(zhí)行命令brew install python3缨硝,windows安裝則需要到官網(wǎng)(http://www.python.org/download/)下載exe文件安裝包, 然后再配置環(huán)境變量,這里就不多詳細(xì)介紹罢低。

Python環(huán)境配置好后查辩,只需要在終端執(zhí)行命令pip install scrapy,這樣Scrapy環(huán)境就已安裝配置完成

  • 項(xiàng)目搭建

在開(kāi)始之前网持,建立一個(gè)新的Scrapy目錄宜岛,進(jìn)入到這個(gè)目錄,并運(yùn)行命令:

scrapy startproject helloScrapy

成功創(chuàng)建會(huì)有如下提示:

You can start your first spider with:
    cd helloScrapy
    scrapy genspider example example.com

這時(shí)就創(chuàng)建好了一個(gè)Scrapy項(xiàng)目, 可以按照這里的提示生成第一個(gè)spider, 第一個(gè)命令是進(jìn)入到helloScrapy文件夾功舀,第二個(gè)命令是生成模板萍倡,也就是在spiders文件夾下自動(dòng)創(chuàng)建文件example.py。自動(dòng)生成了name辟汰、allowed_domains遣铝、start_urls等屬性和parse方法佑刷。name為spiders名,后面執(zhí)行命令時(shí)只需要指定它就可以酿炸,allowed_domains為允許的域名訪問(wèn)瘫絮,非該一級(jí)域名的網(wǎng)站都會(huì)被過(guò)濾掉,start_urls為開(kāi)始爬取的網(wǎng)站url填硕,該屬性是一個(gè)數(shù)組可以為多個(gè)麦萤,parse方法為默認(rèn)爬取到的所有數(shù)據(jù)回調(diào),通過(guò)response對(duì)象接收扁眯,后面做處理都是通過(guò)response來(lái)搜索查詢數(shù)據(jù)壮莹。簡(jiǎn)單說(shuō)下項(xiàng)目的各個(gè)文件:

scrapy.cfg 為項(xiàng)目部署文件
items.py 為項(xiàng)目實(shí)體類(lèi)文件
middlewares.py 為項(xiàng)目中間件文件
pipelines.py 為項(xiàng)目管道文件
settings.py 為項(xiàng)目設(shè)置配置文件
spiders文件夾用于存放Scrapy爬蟲(chóng)文件
example.py 是需要開(kāi)發(fā)設(shè)計(jì)的爬蟲(chóng)文件

  • 設(shè)計(jì)items.py

這個(gè)文件存放的是Scrapy爬蟲(chóng)項(xiàng)目自定義封裝的實(shí)體對(duì)象,需要爬取的元素都在這個(gè)類(lèi)里面申明姻檀,這里我們以(http://quotes.toscrape.com/tag/humor/)這個(gè)網(wǎng)站的數(shù)據(jù)來(lái)學(xué)習(xí)命满,設(shè)計(jì)item.py如下:

class HelloscrapyItem(scrapy.Item):
    text = scrapy.Field()
    author = scrapy.Field()
    tags = scrapy.Field()
    description = scrapy.Field()
    pass
  • 設(shè)計(jì)example.py

需要修改allowed_domainsstart_urlsparse(self, response)方法绣版,并添加parse_author(self, response)方法

# -*- coding: utf-8 -*-
import scrapy
from helloScrapy.items import HelloscrapyItem

class ExampleSpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['quotes.toscrape.com']
    start_urls = ['http://quotes.toscrape.com/tag/humor/']

    def parse(self, response):
        for quote in response.css('div.quote'):
            item = HelloscrapyItem()
            #用strip()方法過(guò)濾開(kāi)頭的\r\n\t和空格符
            item['text'] = quote.css('span.text::text').extract_first().strip()
            item['author'] = quote.css('small.author::text').extract_first().strip()
            item['tags'] = quote.css('div.tags a.tag::text').extract()

            author_page = quote.css('small.author+a::attr(href)').extract_first()
            yield scrapy.Request(url = response.urljoin(author_page), meta={'item': item}, callback=self.parse_author)

            next_page = response.css('li.next a::attr("href")').extract_first()
            if next_page is not None:
                yield scrapy.Request(response.urljoin(next_page), callback=self.parse)

    def parse_author(self, response):
        item = response.meta['item']
        item['description'] = {
            'author_born_date': response.css('.author-born-date::text').extract_first().strip(),
            'author_born_location': response.css('.author-born-location::text').extract_first().strip(),
            'authro_description': response.css('.author-born-description::text').extract_first().strip(),
        }
        yield item
        pass

parse方法中response參數(shù)是封裝返回網(wǎng)頁(yè)的所有數(shù)據(jù)毕莱,通過(guò)該參數(shù)對(duì)象可以獲取任何你想要數(shù)據(jù)扮念。

這里是通過(guò)css選擇器來(lái)獲取數(shù)據(jù),也可以通過(guò)xpath選擇器來(lái)獲取,看個(gè)人喜好奉芦,不過(guò)推薦使用css選擇器疚漆,它的語(yǔ)言簡(jiǎn)潔桂敛,運(yùn)行速度更快缀遍。

通過(guò)瀏覽器的F12或?qū)χW(wǎng)站上的數(shù)據(jù)鼠標(biāo)右鍵檢查,就可以定位到對(duì)應(yīng)html代碼區(qū)域杭朱,根據(jù)html代碼可知阅仔,class=quote的div有多個(gè),分別對(duì)應(yīng)每條數(shù)據(jù)的Item弧械,每個(gè)div下面有詳細(xì)數(shù)據(jù)霎槐,所以我們可以通過(guò)response.css('div.quote')來(lái)獲取到這一頁(yè)面quote的數(shù)組列表,然后循環(huán)它梦谜,拿到里面的詳細(xì)數(shù)據(jù)丘跌。例如我們要拿到author數(shù)據(jù),可以看到quote div下面有一個(gè)class=author的small標(biāo)簽唁桩,所以我們可以通過(guò)quote.css('span.text::text').extract_first().strip()來(lái)獲取數(shù)據(jù)闭树,其中extract_first()方法是獲取到第一個(gè)符合的數(shù)據(jù),strip()方法是過(guò)濾過(guò)濾開(kāi)頭的\r\n\t和空格符荒澡。其它數(shù)據(jù)也是按照相同的方式去獲取报辱。

item html 預(yù)覽圖

我們可以看到quote div下有一個(gè)about鏈接進(jìn)入到關(guān)于頁(yè)面,通過(guò)css選擇器我們可以獲得這個(gè)鏈接地址quote.css('small.author+a::attr(href)').extract_first(),再通過(guò)response.urljoin(author_page)補(bǔ)全地址信息单山,最后通過(guò)scrapy.Request來(lái)發(fā)送一個(gè)請(qǐng)求碍现,用parse_author回調(diào)方法接收幅疼,從上面的代碼可以看到傳遞了一個(gè)meta={'item': item},目的是為了拿到關(guān)于頁(yè)面的數(shù)據(jù)存儲(chǔ)到item中再返回回來(lái)昼接,關(guān)于頁(yè)面的數(shù)據(jù)也是一樣通過(guò)css選擇器獲取爽篷,這里就不多做解釋。

about html代碼預(yù)覽圖

最后我們會(huì)發(fā)現(xiàn)有下一頁(yè)慢睡,如何去拿下一頁(yè)數(shù)據(jù)呢逐工?其實(shí)也很簡(jiǎn)單。通過(guò)css選擇器拿到下一頁(yè)的地址response.css('li.next a::attr("href")').extract_first(),然后判斷存不存在下一頁(yè)這個(gè)標(biāo)簽漂辐,表示有沒(méi)有下一頁(yè)泪喊,同樣是通過(guò)scrapy.Request發(fā)送請(qǐng)求,不過(guò)這里用自身parse方法回調(diào)髓涯,因?yàn)檫壿嫶a都一樣所以就直接可以調(diào)用自身袒啼。

簡(jiǎn)單在介紹下css選擇器:
.quote 選擇class=quote的所有元素
#quote 選擇id=quote的所有元素
* 選擇所有元素
div 選擇<div>的所有元素
div,p 選擇所有<div>元素和所有<p>元素
div p 選擇<div>元素內(nèi)部的所有<p>元素
div>p 選擇父元素為<div>元素的所有<p>元素
div+p 選擇緊接在<div>元素之后的所有<p>元素
[title] 選擇帶有title屬性所有元素
[title=value] 選擇title="value"的所有元素
以上是簡(jiǎn)單的css選擇器用法,更過(guò)用法可以在前面介紹的相關(guān)學(xué)習(xí)資料網(wǎng)站中查看

  • 運(yùn)行scrapy
crapy crawl example

通過(guò)上面命令代碼執(zhí)行即可纬纪。example是之前通過(guò)scrapy genspider example example.com里的值蚓再,也可以在代碼中修改name屬性來(lái)更改這個(gè)值。只執(zhí)行這個(gè)命令不會(huì)保存任何數(shù)據(jù)育八,如果需要保存數(shù)據(jù)到文件中,則需要執(zhí)行命令來(lái)保存

crapy crawl example -o example.json

保存到example.json文件中, 這里保存的是json格式赦邻,還可以保存'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle'這些文件格式髓棋。

  • 設(shè)置請(qǐng)求頭

很簡(jiǎn)單,只需要添加start_requests(self)方法惶洲,去掉start_urls屬性按声,加上headers屬性。

headers = {
    'User-Agent': "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
}

def start_requests(self):
    url = 'http://quotes.toscrape.com/tag/humor/'
    yield scrapy.Request(url, headers=self.headers, callback=self.parse)

這里header只添加了User-Agent恬吕,如果設(shè)置全局User-Agent的話可以再setting.py中添加USER_AGENT = ''即可签则。

  • 設(shè)置代理Proxy

首先在setting.py中添加PROXIES屬性:

PROXIES = [
'http://84.47.174.197:8080',
'http://13.232.75.24:80'
]

然后再middlewares.py中添加ProxyMiddleware類(lèi):

class ProxyMiddleware(object):
    '''
    設(shè)置Proxy
    '''
    def __init__(self, ip):
        self.ip = ip

    @classmethod
    def from_crawler(cls, crawler):
        return cls(ip=crawler.settings.get('PROXIES'))

    def process_request(self, request, spider):
        ip = random.choice(self.ip)
        request.meta['proxy'] = ip

最后在setting.py中開(kāi)啟,注意的是helloScrapy是項(xiàng)目名

DOWNLOADER_MIDDLEWARES = {
   'helloScrapy.middlewares.HttpbinProxyMiddleware': 543,
}

以上三步就可以實(shí)現(xiàn)代理請(qǐng)求了,如果PROXIES有多個(gè)铐料,則會(huì)隨機(jī)切換渐裂。很多網(wǎng)站都會(huì)有反爬蟲(chóng)機(jī)制,訪問(wèn)太頻繁钠惩,ip會(huì)被拉入黑名單柒凉,所以設(shè)置代理就很有必要。

  • 設(shè)置robots協(xié)議

setting.py中可以看到ROBOTSTXT_OBEY = True篓跛,默認(rèn)是True表示遵守robots.txt的規(guī)則膝捞。robots.txt 是遵循Robot協(xié)議的一個(gè)文件,它保存在網(wǎng)站的服務(wù)器中愧沟,它的作用是蔬咬,告訴搜索引擎爬蟲(chóng)鲤遥,本網(wǎng)站哪些目錄下的網(wǎng)頁(yè)不希望你進(jìn)行爬取收錄。在Scrapy啟動(dòng)后林艘,會(huì)在第一時(shí)間訪問(wèn)網(wǎng)站的robots.txt 文件盖奈,然后決定該網(wǎng)站的爬取范圍。所以某些時(shí)候北启,我們就要將此配置項(xiàng)設(shè)置為False卜朗,拒絕遵守Robot協(xié)議!

以上就是網(wǎng)絡(luò)爬蟲(chóng)篇的全部?jī)?nèi)容咕村,通過(guò)上面學(xué)習(xí)场钉,大家可以爬取大部分的網(wǎng)站了。如果喜歡這篇文章的內(nèi)容懈涛,可以關(guān)注我的個(gè)人公眾號(hào)Soaic逛万,第一時(shí)間獲取相關(guān)文章~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市批钠,隨后出現(xiàn)的幾起案子宇植,更是在濱河造成了極大的恐慌,老刑警劉巖埋心,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件指郁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡拷呆,警方通過(guò)查閱死者的電腦和手機(jī)闲坎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茬斧,“玉大人腰懂,你說(shuō)我怎么就攤上這事∠畋” “怎么了绣溜?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)娄蔼。 經(jīng)常有香客問(wèn)我怖喻,道長(zhǎng),這世上最難降的妖魔是什么岁诉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任罢防,我火速辦了婚禮,結(jié)果婚禮上唉侄,老公的妹妹穿的比我還像新娘咒吐。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布恬叹。 她就那樣靜靜地躺著候生,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绽昼。 梳的紋絲不亂的頭發(fā)上唯鸭,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音硅确,去河邊找鬼目溉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛菱农,可吹牛的內(nèi)容都是我干的缭付。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼循未,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼陷猫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起的妖,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绣檬,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后嫂粟,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體娇未,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年星虹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了零抬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搁凸,死狀恐怖媚值,靈堂內(nèi)的尸體忽然破棺而出狠毯,到底是詐尸還是另有隱情护糖,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布嚼松,位于F島的核電站嫡良,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏献酗。R本人自食惡果不足惜寝受,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罕偎。 院中可真熱鬧很澄,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至讯蒲,卻和暖如春痊土,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背墨林。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工赁酝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人旭等。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓酌呆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親辆雾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肪笋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容