詳解如何用Python寫個(gè)聽小說的爬蟲
在路上發(fā)現(xiàn)好多人都喜歡用耳機(jī)聽小說,同事居然可以一整天的帶著一只耳機(jī)聽小說。小編表示非常的震驚。今天就用 Python 下載聽小說 tingchina.com的音頻。

書名和章節(jié)列表
隨機(jī)點(diǎn)開一本書,這個(gè)頁面可以使用 BeautifulSoup 獲取書名和所有單個(gè)章節(jié)音頻的列表。復(fù)制瀏覽器的地址,如:https://www.tingchina.com/yousheng/disp_31086.htm。

from?bs4?import?BeautifulSoup
import?requests
import?re
import?random
import?os
headers?=?{
????'user-agent':?'Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/91.0.4472.114?Safari/537.36'
}
def?get_detail_urls(url):
????url_list?=?[]
????response?=?requests.get(url,?headers=headers)
????response.encoding?=?'gbk'
????soup?=?BeautifulSoup(response.text,?'lxml')
????name?=?soup.select('.red12')[0].strong.text
????if?not?os.path.exists(name):
????????os.makedirs(name)
????div_list?=?soup.select('div.list?a')
????for?item?in?div_list:
????????url_list.append({'name':?item.string,?'url':?'https://www.tingchina.com/yousheng/{}'.format(item['href'])})
????return?name,?url_list
音頻地址
打開單個(gè)章節(jié)的鏈接,在 Elements 面板用章節(jié)名稱作為搜索詞,在底部發(fā)現(xiàn)了一個(gè) script,這一部分就是聲源的地址。

在 Network 面板可以看到,聲源的 url 域名和章節(jié)列表的域名是不一樣的。在獲取下載鏈接的時(shí)候需要注意這一點(diǎn)。

def?get_mp3_path(url):
????response?=?requests.get(url,?headers=headers)
????response.encoding?=?'gbk'
????soup?=?BeautifulSoup(response.text,?'lxml')
????script_text?=?soup.select('script')[-1].string
????fileUrl_search?=?re.search('fileUrl=?"(.*?)";',?script_text,?re.S)
????if?fileUrl_search:
????????return?'https://t3344.tingchina.com'?+?fileUrl_search.group(1)
下載
驚喜總是突如其來,把這個(gè) https://t3344.tingchina.com/xxxx.mp3 放入瀏覽器中運(yùn)行居然是 404。

肯定是少了關(guān)鍵性的參數(shù),回到上面 Network 仔細(xì)觀察 mp3 的 url,發(fā)現(xiàn)在 url 后面帶了一個(gè) key 的關(guān)鍵字。如下圖,這個(gè) key 是來自于 https://img.tingchina.com/play/h5_jsonp.asp?0.5078556568562795 的返回值,可以使用正則表達(dá)式將 key 取出來。

def?get_key(url):
????url?=?'https://img.tingchina.com/play/h5_jsonp.asp?{}'.format(str(random.random()))
????headers['referer']?=?url
????response?=?requests.get(url,?headers=headers)
????matched?=?re.search('(key=.*?)";',?response.text,?re.S)
????if?matched:
????????temp?=?matched.group(1)
????????return?temp[len(temp)-42:]
最后的最后在 __main__ 中將以上的代碼串聯(lián)起來。
if?__name__?==?"__main__":
????url?=?input("請輸入瀏覽器書頁的地址:")
????dir,url_list?=?get_detail_urls()
????for?item?in?url_list:
????????audio_url?=?get_mp3_path(item['url'])
????????key?=?get_key(item['url'])
????????audio_url?=?audio_url?+?'?key='?+?key
????????headers['referer']?=?item['url']
????????r?=?requests.get(audio_url,?headers=headers,stream=True)
????????with?open(os.path.join(dir,?item['name']),'ab')?as?f:
????????????f.write(r.content)
????????????f.flush()
完整代碼
from bs4 import BeautifulSoup
import requests
import re
import random
import os
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
}
def get_detail_urls(url):
url_list = []
response = requests.get(url, headers=headers)
response.encoding = 'gbk'
soup = BeautifulSoup(response.text, 'lxml')
name = soup.select('.red12')[0].strong.text
if not os.path.exists(name):
os.makedirs(name)
div_list = soup.select('div.list a')
for item in div_list:
url_list.append({'name': item.string, 'url': 'https://www.tingchina.com/yousheng/{}'.format(item['href'])})
return name, url_list
def get_mp3_path(url):
response = requests.get(url, headers=headers)
response.encoding = 'gbk'
soup = BeautifulSoup(response.text, 'lxml')
script_text = soup.select('script')[-1].string
fileUrl_search = re.search('fileUrl= "(.*?)";', script_text, re.S)
if fileUrl_search:
return 'https://t3344.tingchina.com' + fileUrl_search.group(1)
def get_key(url):
url = 'https://img.tingchina.com/play/h5_jsonp.asp?{}'.format(str(random.random()))
headers['referer'] = url
response = requests.get(url, headers=headers)
matched = re.search('(key=.*?)";', response.text, re.S)
if matched:
temp = matched.group(1)
return temp[len(temp)-42:]
if __name__ == "__main__":
url = input("請輸入瀏覽器書頁的地址:")
dir,url_list = get_detail_urls()
for item in url_list:
audio_url = get_mp3_path(item['url'])
key = get_key(item['url'])
audio_url = audio_url + '?key=' + key
headers['referer'] = item['url']
r = requests.get(audio_url, headers=headers,stream=True)
with open(os.path.join(dir, item['name']),'ab') as f:
f.write(r.content)
f.flush()總結(jié)
這個(gè) Python 爬蟲比較簡單,小編的每個(gè)月 30 元的流量都不夠用,有了這個(gè)小程序在地鐵上就可以不用流量聽小說了。
以上就是詳解如何用Python寫個(gè)聽小說的爬蟲的詳細(xì)內(nèi)容,更多關(guān)于Python爬蟲 聽小說的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Python代碼實(shí)現(xiàn)Linux中的ls遍歷目錄命令的實(shí)例代碼
這次我就要試著用 Python 來實(shí)現(xiàn)一下 Linux 中的 ls 命令, 小小地證明下 Python 的不簡單,需要的朋友可以參考下2019-09-09
Python?正則表達(dá)式基礎(chǔ)知識點(diǎn)及實(shí)例
在本篇文章里小編給大家整理了關(guān)于Python正則表達(dá)式的一些基礎(chǔ)知識點(diǎn)以及相關(guān)用法實(shí)例內(nèi)容,需要的朋友們可以參考下。2021-12-12
numpy中np.nditer、flags=[multi_index] 的用法說明
這篇文章主要介紹了numpy中np.nditer、flags=['multi_index'] 的用法說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05
Python獲取任意xml節(jié)點(diǎn)值的方法
這篇文章主要介紹了Python獲取任意xml節(jié)點(diǎn)值的方法,涉及Python操作XML節(jié)點(diǎn)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05
如何用Python和JS實(shí)現(xiàn)的Web SSH工具
這篇文章主要介紹了如何用Python和JS實(shí)現(xiàn)的Web SSH工具,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
Python使用Opencv實(shí)現(xiàn)圖像特征檢測與匹配的方法
這篇文章主要介紹了Python使用Opencv實(shí)現(xiàn)圖像特征檢測與匹配的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
python實(shí)現(xiàn)zabbix發(fā)送短信腳本
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)zabbix發(fā)送短信腳本,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09

