Python的創世人是吉多·范羅蘇姆。1989年圣誕節期間,吉多為了在阿姆斯特丹打發時間,決心開發一個新的腳本解釋程序作為ABC語言的一種繼承。ABC是由吉多參加設計的一種教學語言。就吉多本人看來,ABC這種語言非常優美和強大,是專門為非專業程序員設計的。但是ABC語言并沒有成功,究其原因,吉多認為是非開放造成的。吉多決心在Python中避免這一錯誤,并獲取了非常好的效果,完美結合了C和其他一些語言,就這樣,Python在吉多手中誕生了。
Python 特點
- 優點:簡單、易學、速度快、免費、開源、高層語言、可移植、解釋性、面向對象、可擴展、可嵌入、豐富的庫、規范的代碼
- 缺點:單行語句、運行速度慢、獨特的語法(通過縮進區分語句關系)
Python應用
Python應用非常廣泛,如系統編程、圖形處理、數學處理、文本處理、數據庫編程、網絡編程、Web編程、多媒體應用、Pymo引擎、黑客編程、網絡爬蟲等,本篇文章就來學習一下Python的網絡爬蟲
Python爬蟲框架
python爬蟲框架有很多,如Scrapy、PySpider、Crawley、Portia、Newspaper、Beautiful Soup、Grab、Cola等,這么多框架不用學很多,學一個就可以,下面我們就來先學下一下比較熱門的Scrapy框架
Scrapy框架
- 簡介
Scrapy是一個用于以一種快速、簡單、可擴展的方式從網站中提取所需要數據的開源框架。用途廣泛,可以用于數據挖掘、監測和自動化測試。Scrapy吸引人的地方在于它是一個框架,任何人都可以根據需求方便的修改。它也提供了多種類型爬蟲的基類,如BaseSpider、sitema等
- 相關學習資料網址
scrapy官網: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
- 配置環境
首先需要配置Python3的環境,mac配置非常簡單,只需要在終端執行命令brew install python3
,windows安裝則需要到官網(http://www.python.org/download/)下載exe文件安裝包, 然后再配置環境變量,這里就不多詳細介紹。
Python環境配置好后,只需要在終端執行命令pip install scrapy
,這樣Scrapy環境就已安裝配置完成
- 項目搭建
在開始之前,建立一個新的Scrapy目錄,進入到這個目錄,并運行命令:
scrapy startproject helloScrapy
成功創建會有如下提示:
You can start your first spider with:
cd helloScrapy
scrapy genspider example example.com
這時就創建好了一個Scrapy項目, 可以按照這里的提示生成第一個spider, 第一個命令是進入到helloScrapy文件夾,第二個命令是生成模板,也就是在spiders文件夾下自動創建文件example.py。自動生成了name、allowed_domains、start_urls等屬性和parse方法。name為spiders名,后面執行命令時只需要指定它就可以,allowed_domains為允許的域名訪問,非該一級域名的網站都會被過濾掉,start_urls為開始爬取的網站url,該屬性是一個數組可以為多個,parse方法為默認爬取到的所有數據回調,通過response對象接收,后面做處理都是通過response來搜索查詢數據。簡單說下項目的各個文件:
scrapy.cfg 為項目部署文件
items.py 為項目實體類文件
middlewares.py 為項目中間件文件
pipelines.py 為項目管道文件
settings.py 為項目設置配置文件
spiders文件夾用于存放Scrapy爬蟲文件
example.py 是需要開發設計的爬蟲文件
- 設計items.py
這個文件存放的是Scrapy爬蟲項目自定義封裝的實體對象,需要爬取的元素都在這個類里面申明,這里我們以(http://quotes.toscrape.com/tag/humor/)這個網站的數據來學習,設計item.py如下:
class HelloscrapyItem(scrapy.Item):
text = scrapy.Field()
author = scrapy.Field()
tags = scrapy.Field()
description = scrapy.Field()
pass
- 設計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()方法過濾開頭的\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
參數是封裝返回網頁的所有數據,通過該參數對象可以獲取任何你想要數據。
這里是通過css選擇器來獲取數據,也可以通過xpath選擇器來獲取,看個人喜好,不過推薦使用css選擇器,它的語言簡潔,運行速度更快。
通過瀏覽器的F12或對著網站上的數據鼠標右鍵檢查,就可以定位到對應html代碼區域,根據html代碼可知,class=quote
的div有多個,分別對應每條數據的Item,每個div下面有詳細數據,所以我們可以通過response.css('div.quote')
來獲取到這一頁面quote的數組列表,然后循環它,拿到里面的詳細數據。例如我們要拿到author數據,可以看到quote div下面有一個class=author
的small標簽,所以我們可以通過quote.css('span.text::text').extract_first().strip()
來獲取數據,其中extract_first()
方法是獲取到第一個符合的數據,strip()
方法是過濾過濾開頭的\r\n\t和空格符。其它數據也是按照相同的方式去獲取。
我們可以看到quote div下有一個about鏈接進入到關于頁面,通過css選擇器我們可以獲得這個鏈接地址quote.css('small.author+a::attr(href)').extract_first()
,再通過response.urljoin(author_page)
補全地址信息,最后通過scrapy.Request
來發送一個請求,用parse_author
回調方法接收,從上面的代碼可以看到傳遞了一個meta={'item': item}
,目的是為了拿到關于頁面的數據存儲到item中再返回回來,關于頁面的數據也是一樣通過css選擇器獲取,這里就不多做解釋。
最后我們會發現有下一頁,如何去拿下一頁數據呢?其實也很簡單。通過css選擇器拿到下一頁的地址response.css('li.next a::attr("href")').extract_first()
,然后判斷存不存在下一頁這個標簽,表示有沒有下一頁,同樣是通過scrapy.Request
發送請求,不過這里用自身parse
方法回調,因為邏輯代碼都一樣所以就直接可以調用自身。
簡單在介紹下css選擇器:
.quote
選擇class=quote
的所有元素
#quote
選擇id=quote
的所有元素
*
選擇所有元素
div
選擇<div>
的所有元素
div,p
選擇所有<div>
元素和所有<p>
元素
div p
選擇<div>
元素內部的所有<p>
元素
div>p
選擇父元素為<div>
元素的所有<p>
元素
div+p
選擇緊接在<div>
元素之后的所有<p>
元素
[title]
選擇帶有title
屬性所有元素
[title=value]
選擇title="value"
的所有元素
以上是簡單的css選擇器用法,更過用法可以在前面介紹的相關學習資料網站中查看
- 運行scrapy
crapy crawl example
通過上面命令代碼執行即可。example是之前通過scrapy genspider example example.com
里的值,也可以在代碼中修改name屬性來更改這個值。只執行這個命令不會保存任何數據,如果需要保存數據到文件中,則需要執行命令來保存
crapy crawl example -o example.json
保存到example.json文件中, 這里保存的是json格式,還可以保存'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle'
這些文件格式。
- 設置請求頭
很簡單,只需要添加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,如果設置全局User-Agent的話可以再setting.py
中添加USER_AGENT = ''
即可。
- 設置代理Proxy
首先在setting.py
中添加PROXIES
屬性:
PROXIES = [
'http://84.47.174.197:8080',
'http://13.232.75.24:80'
]
然后再middlewares.py
中添加ProxyMiddleware
類:
class ProxyMiddleware(object):
'''
設置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
中開啟,注意的是helloScrapy
是項目名
DOWNLOADER_MIDDLEWARES = {
'helloScrapy.middlewares.HttpbinProxyMiddleware': 543,
}
以上三步就可以實現代理請求了,如果PROXIES有多個,則會隨機切換。很多網站都會有反爬蟲機制,訪問太頻繁,ip會被拉入黑名單,所以設置代理就很有必要。
- 設置robots協議
在setting.py
中可以看到ROBOTSTXT_OBEY = True
,默認是True表示遵守robots.txt的規則。robots.txt 是遵循Robot協議的一個文件,它保存在網站的服務器中,它的作用是,告訴搜索引擎爬蟲,本網站哪些目錄下的網頁不希望你進行爬取收錄。在Scrapy啟動后,會在第一時間訪問網站的robots.txt 文件,然后決定該網站的爬取范圍。所以某些時候,我們就要將此配置項設置為False,拒絕遵守Robot協議!
以上就是網絡爬蟲篇的全部內容,通過上面學習,大家可以爬取大部分的網站了。如果喜歡這篇文章的內容,可以關注我的個人公眾號
Soaic
,第一時間獲取相關文章~