知識(shí)有價(jià)
公眾號(hào)從5月31號(hào)開(kāi)始第一次發(fā)文,到現(xiàn)在快一個(gè)月了。27天的時(shí)間里,更新了26篇文章。因?yàn)楦杏X(jué)每天更新身體有些扛不住,所以從上周開(kāi)始,每周五給自己放個(gè)假,找朋友擼擼串,和同學(xué)懷念下10年前的dota1。
今天很開(kāi)心,公司內(nèi)部博客網(wǎng)站中,一個(gè)項(xiàng)目舉辦了相關(guān)的活動(dòng),具體活動(dòng)的細(xì)節(jié)我也是今天才知道。大概評(píng)獎(jiǎng)規(guī)則以作者文章獲取贊賞或者推薦次數(shù)進(jìn)行排名。之前寫(xiě)的flask制作美觀的網(wǎng)頁(yè)日歷,獲得了贊賞第一名,獎(jiǎng)品為200塊的京東卡。
登陸系統(tǒng)看了下,除了這篇文章還有好幾篇獲得了同事們的打賞鼓勵(lì),加起來(lái)差不多20多塊吧。
其實(shí)打賞這個(gè)東西,作者關(guān)注的的不是金額,你給一分也是愛(ài)。他們更在意的是獲得大家的肯定與鼓勵(lì),所以在這里感謝那些陌生的朋友們對(duì)我文章的肯定。
今天說(shuō)說(shuō)requests-plus模塊
requests模塊為urllib(urllib3)的封裝模塊,它的存在使得網(wǎng)絡(luò)請(qǐng)求變得so easy!那么requests-plus模塊又是個(gè)什么鬼?朋友們要說(shuō)了,你個(gè)大忽悠,我百度搜了哪里有這個(gè)模塊。是的,沒(méi)這個(gè)模塊,開(kāi)局一個(gè)詞,其他全靠編,哈哈。
有接觸爬蟲(chóng)的朋友們應(yīng)該都知道,requests配合beautifulsoup,簡(jiǎn)直是雙劍合璧。一個(gè)用于訪問(wèn)網(wǎng)站并獲取html內(nèi)容,另一個(gè)用來(lái)解析html??山裉靝lus選手將它們的功能合二為一了,模塊名為requests_html。
python模塊學(xué)習(xí)建議
學(xué)習(xí)python模塊,給大家個(gè)我自己不專(zhuān)業(yè)的建議:
- 養(yǎng)成習(xí)慣,遇到一個(gè)模塊,先去github上看看開(kāi)發(fā)者們關(guān)于它的說(shuō)明,而不是直接百度看別人寫(xiě)了什么東西。也許后者可以讓你很快入門(mén),可那樣你更多的是在吃別人剩下的。而訪問(wèn)Github,你可以在里面獲取到更多作者想告訴你的內(nèi)容和相關(guān)的鏈接地址。怎么評(píng)估一個(gè)模塊好不好,最簡(jiǎn)單的辦法就是看star,requests_html的star:9794,已經(jīng)算很高的了。
requests_html的Git地址:https://github.com/kennethreitz/requests-html。作者提供了官網(wǎng)http://html.python-requests.org/,用于更詳細(xì)的使用描述。 - python模塊下載,多數(shù)情況大家使用
pip install xxxx輕松搞定。但請(qǐng)記住這個(gè)網(wǎng)址:https://pypi.org/。在你下載模塊前,先去搜索下它,看看pypi給你什么提示與要求。
就比如requests_html,官方明確說(shuō)明了,最新版本的requests-html 0.10.0 Requires: Python >=3.6.0。而支持3.5的最后一個(gè)版本是pip install requests-html==0.6.6
requests-html學(xué)習(xí)
安裝
python3.6+ pip install requests-html
python3.5 pip install requests-html==0.6.6
再?gòu)?qiáng)調(diào)一次,requests_html僅支持3.5+,且最新版本的requests_html僅支持3.6+ ,3.5的最后一個(gè)版本為0.6.6。
安裝時(shí),你會(huì)發(fā)現(xiàn),requests-html依賴(lài)了很多其他模塊,統(tǒng)一封裝后,讓開(kāi)發(fā)變得更加無(wú)腦:
Successfully installed appdirs-1.4.3 bs4-0.0.1 certifi-2019.3.9 chardet-3.0.4
cssselect-1.0.3 fake-useragent-0.1.11 idna-2.8 lxml-4.3.3 parse-1.12.0
pyee-6.0.0 pyppeteer-0.0.25 pyquery-1.4.0 requests-2.22.0 requests-html-0.10.0
six-1.12.0 tqdm-4.32.1 w3lib-1.20.0 websockets-7.0
官網(wǎng)介紹
全面支持解析JavaScript!
CSS 選擇器 (jQuery風(fēng)格, 感謝PyQuery).
XPath 選擇器, for the faint at heart.
自定義user-agent (就像一個(gè)真正的web瀏覽器).
自動(dòng)追蹤重定向.
連接池與cookie持久化.
令人欣喜的請(qǐng)求體驗(yàn),魔法般的解析頁(yè)面.
舉幾個(gè)毛栗子
下面舉幾個(gè)官網(wǎng)的栗子,內(nèi)容來(lái)自:http://html.python-requests.org/
from requests_html import HTMLSession
session = HTMLSession()
r = session.get('https://www.baidu.com/')
獲取網(wǎng)頁(yè)內(nèi)容
print(r.html.html)獲取鏈接
print(r.html.links)
print(r.html.absolute_links)
links和absolute_links兩個(gè)屬性分別返回HTML對(duì)象所包含的所有鏈接和絕對(duì)鏈接(均不包含錨點(diǎn))通過(guò)CSS選擇器獲取元素
r.html.find([selector],[first=True])
selector選擇器,使用jQuery風(fēng)格。如果不熟悉,給你個(gè)jQuery的官網(wǎng)傳送門(mén):https://api.jquery.com/category/selectors/
添加first=True則為find ,不添加則為findAll,簡(jiǎn)潔明了...
但需要注意,如果沒(méi)有添加first=True,即便返回一個(gè)元素,結(jié)果也將是list類(lèi)型通過(guò)xpath獲取元素
r.html.xpath('//*[@id="su"]', first=True) # 獲取百度一下按鈕地址...元素具體內(nèi)容
# 獲取網(wǎng)站html內(nèi)容
r.html.html
# 獲取網(wǎng)站文本內(nèi)容
r.html.text
# 上面?zhèn)z內(nèi)容太多就不打印了...
# 獲取元素的屬性
print(r.html.xpath('//*[@id="su"]', first=True).attrs)
output:
{'class': ('bg', 's_btn'), 'id': 'su', 'type': 'submit', 'value': '百度一下'}
- JavaScript支持
requests_html的js執(zhí)行是亮點(diǎn),但是毀在了默認(rèn)安裝上...
r.html.render() 首次執(zhí)行該方法是,模塊會(huì)檢查依賴(lài),并下載chromium,chromium是什么鬼,看起來(lái)很像chrome?
搞過(guò)selenium的應(yīng)該知道,這里簡(jiǎn)單對(duì)比下chrome和chromium:
- Chromium是谷歌的開(kāi)源項(xiàng)目,開(kāi)發(fā)者們可以共同去改進(jìn)它,然后谷歌會(huì)收集改進(jìn)后的Chromium并發(fā)布改進(jìn)后安裝包。Chrome不是開(kāi)源項(xiàng)目,谷歌會(huì)把Chromium的東西更新到Chrome中。你也可以這么理解Chromium是體驗(yàn)版,Chrome是正式版;
- Chromium不用安裝,下載下來(lái)的是壓縮包,解壓后直接就可以使用。Chrome需要安裝;
- Chromium功能比Chrome多,因?yàn)樾鹿δ芏际窍仍贑hromium中使用,等完善后才添加到Chrome中。相對(duì)的Chrome就要比Chromium穩(wěn)定很多不容易出錯(cuò);
- Chromium不開(kāi)放自動(dòng)更新功能,所以用戶需手動(dòng)下載更新,而Chrome則可自動(dòng)連上Google的服務(wù)器更新,但新版的推出很慢。
但是,模塊在安裝的時(shí)候由于SSLCertVerificationError問(wèn)題,沒(méi)辦法進(jìn)行自動(dòng)化安裝:
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='storage.googleapis.com', port=443): Max retries exceeded with url: /chromium-browser-snapshots/Win_x64/575458/chrome-win32.zip (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)')))
好在模塊給出了地址,拼接host和uri即可進(jìn)行下載:
http://storage.googleapis.com//chromium-browser-snapshots/Win_x64/575458/chrome-win32.zip
我家里下載好慢,這點(diǎn)就不演示了,大家對(duì)這官網(wǎng)扭一扭吧...
requests-html示例
到了今天今天的重點(diǎn)了,使用requests-html獲取2019中國(guó)虛假大學(xué)!
“虛假大學(xué)”是未在教育部備案,不具備招生資格、沒(méi)有辦學(xué)資質(zhì)、涉嫌非法招生和網(wǎng)絡(luò)詐騙的“虛假大學(xué)”。
這些虛假大學(xué)數(shù)據(jù)統(tǒng)計(jì),來(lái)源于人民日?qǐng)?bào)。其中還鬧過(guò)一個(gè)笑話,一個(gè)網(wǎng)站轉(zhuǎn)載人民日?qǐng)?bào)的這條新聞時(shí),誤將中國(guó)郵電大學(xué)寫(xiě)成了北京郵電大學(xué),結(jié)果北郵發(fā)飆要求該媒體即刻修改并致歉!然后,人民日?qǐng)?bào)表示躺著也中槍.為人民日?qǐng)?bào)獻(xiàn)上一首白智英的像中槍一樣。
好了不發(fā)散回正題,為了演示requests-html示例,找到了這個(gè)網(wǎng)站:
高三網(wǎng):http://www.gaosan.com/gaokao/249708.html
網(wǎng)站以文本的格式,列出了392所虛假大學(xué)名單!那么,我們就用requests-html,獲取一下它的數(shù)據(jù),讓你們看看requests-html有多簡(jiǎn)單!

分析下下網(wǎng)站結(jié)構(gòu),清楚明白,數(shù)據(jù)包裹在
<div id="data249708">內(nèi)部,從第三個(gè)p標(biāo)簽開(kāi)始為我們所需要的數(shù)據(jù)。
代碼實(shí)現(xiàn):
# -*- coding: utf-8 -*-
# @Author : 王翔
# @JianShu : 清風(fēng)Python
# @Date : 2019/6/27 1:28
# @Software : PyCharm
# @version :Python 3.7.3
# @File : PseudoCollege.py
from requests_html import HTMLSession
import json
class PseudoCollege:
def __init__(self, url):
self.url = url
self.headers = {"User-Agent": ("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36")
}
def get_response(self):
session = HTMLSession()
return session.get(self.url, headers=self.headers)
def filter_info(self):
html_data = self.get_response()
# 從第三個(gè)P標(biāo)簽開(kāi)始,獲取虛假大學(xué)數(shù)據(jù)
return html_data.html.find('div#data249708 p')[2:]
@staticmethod
def get_json(data):
info = {}
city = None
for line in data:
# 每個(gè)城市會(huì)顯示為 <p><strong>北京:151所</strong></p>
if 'strong' in line.html:
# 拆分城市與虛假大學(xué)數(shù)量
city, total_college = line.text.split(':')
# 構(gòu)造字典
info[city] = dict(total=total_college, data=[])
continue
info[city]['data'].append(line.text)
with open('colleges.json', 'w+', encoding='utf-8') as f:
# ensure_ascii默認(rèn)為T(mén)rue,json.dump后會(huì)被轉(zhuǎn)碼...
f.write(json.dumps(info, ensure_ascii=False))
def run():
url = 'http://www.gaosan.com/gaokao/249708.html'
main = PseudoCollege(url)
data = main.filter_info()
main.get_json(data)
if __name__ == '__main__':
run()
叫College感覺(jué)有點(diǎn)諷刺...最終將這些學(xué)校保存至colleges.json的文本中,我看看結(jié)果片段:
... ... ,
"陜西": {
"total": "16所",
"data": [
"西安電子信息學(xué)院",
"西安理工學(xué)院",
"西安工商學(xué)院",
"西安科技師范大學(xué)",
"西安信息技術(shù)學(xué)院",
"西安工商管理學(xué)院",
"西安工業(yè)科技技術(shù)學(xué)院",
"西安工業(yè)科技學(xué)院",
"陜西國(guó)防工業(yè)技術(shù)學(xué)院",
"陜西瀚林醫(yī)科學(xué)院",
"西安工業(yè)工程學(xué)院",
"陜西工貿(mào)職業(yè)學(xué)院",
"西安科技職業(yè)學(xué)院",
"西安經(jīng)濟(jì)技術(shù)學(xué)院",
"西安機(jī)電工程學(xué)院",
"陜西科技管理學(xué)院"
]
},
"福建": {
"total": "5所",
"data": [
"廈門(mén)師范學(xué)院",
"福建海峽經(jīng)貿(mào)技術(shù)學(xué)院",
"福建經(jīng)濟(jì)貿(mào)易大學(xué)",
"福建科技學(xué)院",
"福建省輕工業(yè)學(xué)院"
]
},
... ...
The End
一個(gè)不留神又搞到二半夜了,哎...
快將這392所虛假大學(xué)名單,傳播給你身邊有孩子高考的朋友吧。
OK,今天的內(nèi)容就到這里,如果覺(jué)得有幫助,歡迎將文章或我的微信公眾號(hào)【清風(fēng)Python】分享給更多喜歡python的人,謝謝。