度娘啊,你以為你把百度網盤取消限速了,我們就滿意了?當然不滿意,還有百度文庫呢!本來好好的檔案,非得不讓我們下載……今天,就教大家跟我一起寫百度文庫下載器Weeker,拒絕文庫,從我做起,
我們的下載器是一個GUI程式,具體架構是,先寫核心檔案(get.py),再寫命令列決議檔案(weeker.py),接著使用Fire生成命令列,最后用Gooey把CLI轉換為GUI,
很多人學習python,不知道從何學起, 很多人學習python,掌握了基本語法過后,不知道在哪里尋找案例上手, 很多已經做案例的人,卻不知道如何去學習更加高深的知識, 那么針對這三類人,我給大家提供一個好的學習平臺,免費領取視頻教程,電子書籍,以及課程的源代碼! QQ群:701698587 歡迎加入,一起討論 一起學習!
準備
安裝
- 安裝Python 3.8;
- 安裝依賴(依賴的作用下文會詳解):pip install requests docx beautifulsoup4 Gooey
目錄
初始化專案(下面的腳本是在Unix或Linux上運行的):
復制代碼 隱藏代碼 cd /path/to/project mkdir Weeker touch get.py weeker.py
爬蟲核心
第一步,打開get.py,先引入類別庫:
復制代碼 隱藏代碼 from os import getcwd, system from re import sub import requests import docx from bs4 import BeautifulSoup
每個模塊的作用如下:
|
模塊名稱 |
作用 |
|
os |
獲取當前目錄 |
|
re |
替換檔案中的特定字符 |
|
requests |
用來做網路請求,不用多說, |
|
docx |
用來將txt轉換為docx格式, |
|
bs4 |
用來把文本從html中決議出來, |
由于保存檔案時我們需要判斷路徑,定義一個pwd常量,用來存盤“當前路徑:
復制代碼 隱藏代碼
pwd = getcwd()
再宣告一個get
url:ua:path:output:convert方法,來實作我們的爬蟲函式,其中:
|
引數名稱 |
作用 |
|
url |
檔案地址,比如隨便搜了一個: |
|
ua |
User Agent,我試了一下,如果使用瀏覽器UA是不行的,會爬到一個廣告界面,然后告訴你此操作需要登錄,因此我們要使用Googlebot或Baiduspider來繞過UA檢測(這就是為什么搜索引擎能搜到),以為我們是一個搜索引擎,跟推薦使用后者,畢竟百度和文庫一家人嘛, |
|
path |
存盤目錄,不包括檔案名, |
|
output |
帶有后綴名的檔案名, |
|
convert |
轉換后的格式, |
撰寫get:::::函式
獲取html&決議
把游標移到get:::::函式,首先照例我們要用requests,并且祭上bs4一條龍決議:
復制代碼 隱藏代碼 headers = { 'User-Agent': ua } result = requests.get(url, headers=headers) soup = BeautifulSoup(res.text, "html.parser") # 為了方便管理文本,我們定義一個陣列用來存盤檔案的每一行 everyline = []
添加標題
我們給檔案先添上標題,也就是網頁的標題,
復制代碼 隱藏代碼
everyline.append(soup.title.string)
但是這樣會有一個問題,添加出來的標題都是“xxxxxxx_百度文庫”,很不雅觀,所以抬上re.sub作替換,改成:
復制代碼 隱藏代碼 everyline.append(re.sub('_百度文庫', '', soup.title.string, 1))
獲取正文
通過觀察網頁,我們發現,bd doc-reader這個class有重大嫌疑,這個class里的東西都是正文內容:
我們通過bs4決議它,發現內容中有很多\n、\x0c和空格,\n是換行符,我們把它分割到陣列中,而后兩者分別洗掉即可:
復制代碼 隱藏代碼 for doc in soup.find_all('div', attrs={"class": "bd doc-reader"}): everyline.extend(doc.get_text().split('\n')) # 擴展陣列 everyline = [i.replace(' ', '') for i in everyline] everyline = [i.replace('\x0c', '') for i in everyline]
保存檔案
接下來就是保存檔案,我的思路是,先按照txt格式保存,然后再判斷convert引數,如果填寫了docx,再將txt加后綴并修改為docx,
復制代碼 隱藏代碼 final_path = path # 如果是相對路徑,連接pwd改成絕對路徑,否則python不支持, if not path.startswith('/'): final_path = pwd + '/' + final_path try: file = open(final_path + '/' + output, 'w', encoding='utf-8') for line in everyline: file.write(line) file.write('\n') file.close() except FileNotFoundError as err: print("wenku: error: Output directory does not exist. Quitting.") exit(1) # 如果有convert請求 if convert == 'docx': with open(final_path + '/' + output) as f: docu = docx.Document() # 創建物件 docu.add_paragraph(f.read()) # 添加段落 docu.save(final_path + '/' + output + '.' + convert) # 保存檔案,檔案名為xxx.xxx.docx system('rm ' + final_path + '/' + output) # 洗掉try中保存的檔案
創建GUI
打開weeker.py,
首先是兩句 import,其中Gooey可以用類似argparse的語法將CLI轉換為GUI,
復制代碼 隱藏代碼 from gooey import Gooey, GooeyParser import get
接著添加if __name__ == '__main__':
復制代碼 隱藏代碼 if __name__ == '__main__': main() 我們來定義一下這個main():
復制代碼 隱藏代碼 @Gooey(encoding='utf-8', program_name="Weeker ", language='chinese') def main(): parser = GooeyParser(description="百度文庫下載器,干杯!") parser.add_argument("url", metavar='檔案地址', widget="TextField") parser.add_argument("ua", metavar='用戶UA', widget="Dropdown", choices={"Googlebot": 1, 'Baiduspider': 2}) parser.add_argument("path", metavar='保存路徑', widget="DirChooser") parser.add_argument("output", metavar='重命名', widget="TextField") parser.add_argument("convert", metavar='格式轉換', widget="Dropdown", choices={'docx': 1}) args = parser.parse_args() get.get(args.url, ua=args.ua, path=args.path, output=args.output, convert=args.convert)
@Gooey是一個修飾器,可以把main()轉換為一個Gooey函式,在main中,我們寫下類似argparse的parser.add_argument函式,最終定義args = parser.parse_args(),從args的成員獲取每個引數的輸入,傳到get.py里,我們運行一下,神奇的一幕發生了:
我們成功地把CLI轉換成了GUI!!!
注I:如果你喜歡命令列,可以GitHub搜python-fire,直接將函式和引數暴漏給CLI,效果更佳,
注II:因為電腦原因,打包不了成品,因此有需要者請自行編譯,
注III:附件里有兩個py檔案,
注IV:我剛看見原始碼里面有一句import寫錯了,如果你下載了原始碼,請先照文中代碼核對一下,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/333245.html
標籤:Python
