百度文库文章提取器(下)
此文章講基于百度文庫文章提取器設計思路的代碼實現,如果你還不知道爬取百度文庫文章的思路請移步:百度文庫文章提取器(上)
git倉庫地址:https://github.com/redstarbrother/wkspider
URL訪問
# request請求函數,返回網頁源碼 def fetch_url(url):global versiontry:content = requests.get(url).content.decode("gbk")except UnicodeDecodeError: # 捕獲編碼異常,如果有異常說明為新版本頁面,用utf-8格式解碼content = requests.get(url).content.decode("utf-8")version[0] = 1return contentversion變量是一個包含兩個元素的列表,分別代表文章版式(新版or舊版)和文章類型(doc、txt…)。函數訪問傳入的url,將response的內容進行gbk解碼,如果出現異常則說明需要用utf-8格式解碼(根據實測,舊版文章只能gbk解碼,而新版文章只能utf-8解碼),同時令version[0]=1。
判斷文章類型
# 判斷文檔類型 def verjud(content):if version[0] == 0:version[1] = re.findall(r"docType.*?\:.*?\'(.*?)\'\,", content)[0] # 通過正則獲取文檔類型# print(version[1])# print(type(version[1]))else:if "indexXreader" in content:version[1] = "doc"elif "indexTxt" in content:version[1] = "txt"# print(version[1])如果是舊版,在網頁源碼中可以通過正則找到docType后面的文章類型。如果是新版,在網頁源代碼的最下方有且僅有indexXreader或indexTxt,分別代表doc和txt。
舊版doc文章爬取
# 舊版doc文檔 def old_doc(content):url_list = re.findall(r'(https.*?0.json.*?)\\x22}', content) # 提取文章所有頁鏈接url_list = [addr.replace("\\\\\\/", "/") for addr in url_list] # 刪掉轉義字符result = []for url in url_list[:int(len(url_list)/2)]: # 提取的鏈接只需要用前一半content = fetch_url(url)temp = ""y = 0txtlists = re.findall('"c":"(.*?)".*?"y":(.*?),', content)for item in txtlists:if not y == item[1]:y = item[1]n = '\n'else:n = ''temp += ntemp += item[0].encode('utf-8').decode('unicode_escape', 'ignore')result.append(temp)return result通過正則將所有文章頁的URL提取出來,在通過replace方法剔除鏈接中的轉義字符,此時的URL才是可以訪問的。遍歷訪問url_list并將文章內容提取出來。
新版doc文章爬取
# 新版doc文檔 def new_doc(content):url_list = re.findall(r'(https:\\\\/\\\\/wkbjcloudbos.*?0.json.*?)\\', content) # 提取文章所有頁鏈接url_list = [addr.replace(r"\\", "") for addr in url_list] # 刪掉轉義字符result = []for url in url_list[:int(len(url_list))]: # 此版本文庫沒有多余鏈接content = fetch_url(url)temp = ""txtlists = re.findall('"c":"(.*?)".*?"y":(.*?),', content)y = 0for item in txtlists:if not y == item[1]:y = item[1]n = '\n'else:n = ''temp += ntemp += item[0].encode('utf-8').decode('unicode_escape', 'ignore')result.append(temp)return result和舊版doc文章除正則表達式其他基本相同。
新版txt文章爬取
# 新版txt文檔 def new_txt(content):txtId = re.findall("show_doc_id\":\"(.*?)\"", content)[0] # 獲取文檔idmd5 = re.findall("md5sum=(.*?)&", content)[0] # 獲取md5sum值sign = re.findall("sign=(.*?)\"", content)[0] # 獲取sign值pageNum = re.findall("\"page\":\"(.*?)\"", content)[0] # 獲取文檔總頁碼數resign = re.findall("\"rsign\":\"(.*?)\"", content)[0] # 獲取resign值url = "https://wkretype.bdimg.com/retype/text/" + txtId + "?md5sum=" + md5 + "&sign=" + sign + "&callback=cb&pn=1&rn=" + pageNum +\"&type=txt&rsign=" + resign # 拼接字符串獲取文檔鏈接# print(url)# text = requests.get(url).content.decode('gbk')txtcontent = json.loads(fetch_url(url)[3:-1]) # 加載json格式文檔result = []for item in txtcontent:temp = ""for i in item['parags']:temp += i['c'].replace('\\r', '\r').replace('\\n', '\n')result.append(temp)return result在網頁源代碼中分別獲取txtId、md5、sign、pageNum、resign,然后拼接URL并訪問,在返回的數據中提取文章內容。
“主函數”
def getarticle(url):# url = "https://wenku.baidu.com/view/dbc53006302b3169a45177232f60ddccda38e63d.html?rec_flag=default&sxts=1584344873233" # 舊版doc# url = "https://wenku.baidu.com/view/62906818227916888486d74f.html?rec_flag=default" # 新版doc# url = "https://wenku.baidu.com/view/ccfb5a96ba68a98271fe910ef12d2af90242a8f5.html?from=search" # 新版txt# url = input('請輸入要下載的文庫URL地址')# return ["123", "456"]content = fetch_url(url)verjud(content)message = []if version[0] == 0:if version[1] == "doc":message = old_doc(content)elif version[1] == "txt":message = old_txt(content)else:passelse:if version[1] == "doc":message = new_doc(content)elif version[1] == "txt":message = new_txt(content)else:pass# for item in message:# print(item)# print("*"*50)return message函數最后message是一個列表,每個元素對應的就是所爬取文章每頁的內容。
文章只展示部分代碼,需要所有源碼請到GitHub自行下載。
原文鏈接: https://www.jhxblog.cn/article/?articleid=21
總結
以上是生活随笔為你收集整理的百度文库文章提取器(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩转oracle 11g(49):监听服
- 下一篇: shell 执行mysql语句