日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对第一次爬虫的完善

發布時間:2024/3/26 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对第一次爬虫的完善 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上次寫完以后好多地方其實自己也沒搞明白,問老師,查網頁,再加自己的思考,做了一定的完善,再次放上來了。

先說數據解析,打開喜馬拉雅,搜索框輸入 : 高中英語聽力,得到幾個搜索結果。先點入一個高一的聽力項目,有4頁92個音頻,可以播放,但是點下載就提示讓你用手機版喜馬拉雅。

瀏覽器按F12進入開發者模式以后,從network項目里反復查看,類型選json,發起者找帶(xhr)的,反復翻頁反復試聽,最后發現 show&id 字樣的項目可以得到一個文件信息列表,

audio&id字樣可以得到單個文件的展示頁面,此頁面里有最終音頻下載地址,沒有可惡的加密,就是明文地址,雖然是間接提供。

上次的代碼,只做了高一的一部分下載,這次把高一到高三的都加上了。

寫程序過程中有個小發現,json格式的數據,布爾值 寫成 true 和 false,但是 python里面,布爾值 必須用 True 和 False。

如果字典形狀的字符串,里面寫的是? true false就可以用json.loads,dict(eval()) 嵌套轉換會失敗;如果寫的是 True False 那么 dict(eval()) 轉換成功 而json.loads轉換失敗。

源碼如下,有些字符串常數寫在了前面,導致可讀性有所下降。

# import re 本次沒用上,學完再來改這個程序 import requests import json import os myheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'} url_1 = "https://www.ximalaya.com/revision/play/v1/show?id=16836545&sort=0&size=30&ptype=1" url_2 = "https://www.ximalaya.com/revision/play/v1/show?id=16836559&sort=0&size=30&ptype=1" url_3 = "https://www.ximalaya.com/revision/play/v1/show?id=16837298&sort=0&size=30&ptype=1" url_4 = "https://www.ximalaya.com/revision/play/v1/show?id=16837328&sort=0&size=30&ptype=1"url_5 = "https://www.ximalaya.com/revision/play/v1/show?id=16770124&sort=0&size=30&ptype=1" url_6 = "https://www.ximalaya.com/revision/play/v1/show?id=16770677&sort=0&size=30&ptype=1" url_7 = "https://www.ximalaya.com/revision/play/v1/show?id=16770707&sort=0&size=30&ptype=1"url_8 = "https://www.ximalaya.com/revision/play/v1/show?id=8262781&sort=1&size=30&ptype=1" url_9 = "https://www.ximalaya.com/revision/play/v1/show?id=8229167&sort=1&size=30&ptype=1"url_11 = "https://www.ximalaya.com/revision/play/v1/show?id=25986688&sort=0&size=30&ptype=1" url_12 = "https://www.ximalaya.com/revision/play/v1/show?id=25987089&sort=0&size=30&ptype=1" url_13 = "https://www.ximalaya.com/revision/play/v1/show?id=25988780&sort=0&size=30&ptype=1" url_14 = "https://www.ximalaya.com/revision/play/v1/show?id=25989223&sort=0&size=30&ptype=1"url_15 = "https://www.ximalaya.com/revision/play/v1/show?id=24015485&sort=0&size=30&ptype=1" url_16 = "https://www.ximalaya.com/revision/play/v1/show?id=24015789&sort=0&size=30&ptype=1" url_17 = "https://www.ximalaya.com/revision/play/v1/show?id=24362802&sort=0&size=30&ptype=1" url_18 = "https://www.ximalaya.com/revision/play/v1/show?id=24362832&sort=0&size=30&ptype=1"url_19 = "https://www.ximalaya.com/revision/play/v1/show?id=21719703&sort=0&size=30&ptype=1" url_1a = "https://www.ximalaya.com/revision/play/v1/show?id=21719733&sort=0&size=30&ptype=1"dirs_list = ["高一專項練習", "高二專項練習", "高三專項練習", "高一強化練習", "高二強化練習","高三強化練習"] urls_list0 = [url_1,url_2,url_3,url_4] urls_list1 = [url_5,url_6,url_7] urls_list2 = [url_8,url_9] urls_list3 = [url_11,url_12,url_13,url_14] urls_list4 = [url_15,url_16,url_17,url_18] urls_list5 = [url_19,url_1a] base1_url = 'https://www.ximalaya.com/revision/play/v1/audio?id=' base2_url = '&ptype=1' leftht, rightht = '"tracksAudioPlay":[', '],"hasMore"' reduce_fld="trackName" # 中文簡介字段名 music_page_idx = "trackId" # 一個索引,用于得到單個文件的獲取頁面def check_find_download(url):resp = requests.get(url, headers = myheaders)html_text = resp.text# print(html_text)print('------------------------')#其實用正則表達式更簡潔,但是我還不會,用了字符串切片,把tracksAudioPlay 和 hasMore 之間的部分切出來以供使用loc_left, loc_right = html_text.find(leftht), html_text.find(rightht)html_text = html_text[loc_left + len(leftht):loc_right]#html_text 是包含30個音樂文件的間接引用信息的大字符串,是30個字典的連接。每個前置URL有30個聲音文件的地址可以解析dict_list = html_text.split(sep = '}')dict_list_len = len(dict_list) - 1del dict_list[dict_list_len] #實測,split拆分出來的最后一個元素是個空串,刪之。# 拆分出來的元素都因為split的使用被丟掉了右側大括號需要補上。除了第一個元素,其他都多了個前置逗號,lstrip丟掉這個逗號for ind in range(dict_list_len):dict_list[ind] = dict_list[ind] + '}'if ind == 0:passelse:dict_list[ind] = dict_list[ind].lstrip(',')# print(dict_list[ind]) dict_list是個每個元素都是字符串的列表,每個元素符合字典形式。for ind in range(dict_list_len):mp3_dic = json.loads(dict_list[ind])mp3_reduce = mp3_dic[reduce_fld] # 取中文簡介的內容存入 mp3_reduce備用music_file_id = mp3_dic[music_page_idx] # 一個索引,用于得到單個文件的獲取頁面print('獲得索引:', music_file_id,' 轉換下載地址……')mp3_url_page = base1_url + str(music_file_id) + base2_url# 這個地址中顯示著最終文件的鏈接,先讀取它,然后解析獲得的文本resp2txt = requests.get(mp3_url_page, headers = myheaders).text# 對 resp2txt 進行切割就可以得到最終地址,本來正則表達式更有效率,可惜我還不會。mu_left, mu_right = '"src":"', '","albumIsSample' #地址字符的前與后標志mu_loc_left, mu_loc_right = resp2txt.find(mu_left), resp2txt.find(mu_right)# find 獲得最終地址的左邊界index和右邊界indexmu_addr = resp2txt[mu_loc_left + len(mu_left):mu_loc_right] #有了邊界,切片# print('地址是', mu_addr ) 好像每必要顯示給用戶看哦。try:with open(mp3_reduce + ".m4a", "wb") as fp: # 二進制新建寫模式打開文件,前綴為之前獲得的中文簡介,后綴為m4a# 其實,應該對 mu_adder 這個最終地址再做解析,取出后綴來給上一行給后綴,而不是粗暴地用 m4a 這個后綴,以后再說吧。fp.write(requests.get(mu_addr).content)print('寫入聽力聲音文件:', mp3_reduce)except Exception as e:print('好像出錯了……', e)returnprint('已解析的下載的項目:', dirs_list) y=input('請按回車鍵繼續……') for inde in range(len(dirs_list)):grade_race = dirs_list[inde]print(grade_race)try:os.mkdir(grade_race)except Exception as e:print('文件夾已存在無需再建立', e)os.chdir(grade_race)if inde == 0:url_list = urls_list0elif inde == 1:url_list = urls_list1elif inde == 2:url_list = urls_list2elif inde == 3:url_list = urls_list3elif inde == 4:url_list = urls_list4else:url_list = urls_list5for this_race in url_list:check_find_download(this_race)os.chdir('..')print('下載已經結束,下載文件為 m4a 格式,') print('請查看您的播放器說明書,了解是否支持播放 m4a 文件!') y = input('請按回車鍵結束!')

開頭的一堆 url ,都是開發者模式里提取出來的 聲音外在信息,用某個id字段可以拼出 mp3_url_page, 是聲音文件的下載頁,mu_addr是解析出來的最終音頻下載地址。

?

總結

以上是生活随笔為你收集整理的对第一次爬虫的完善的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。