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)
- 優(yōu)點(diǎn):簡(jiǎn)單介蛉、易學(xué)萌庆、速度快、免費(fèi)币旧、開(kāi)源踊兜、高層語(yǔ)言、可移植佳恬、解釋性捏境、面向?qū)ο蟆⒖蓴U(kuò)展毁葱、可嵌入垫言、豐富的庫(kù)、規(guī)范的代碼
- 缺點(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_domains
、start_urls
和parse(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ù)也是按照相同的方式去獲取报辱。
我們可以看到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選擇器獲取爽篷,這里就不多做解釋。
最后我們會(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)文章~