日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

考慮到現在大部分小伙伴使用 Python 主要因為爬蟲,那么為了更好地幫助大家鞏固爬蟲知識,加深對爬蟲的理解,選擇了爬取百度文庫作為我們的目標。

教你用 Python 爬取 Baidu 文庫全格式文檔

 

廢話不多說,我們開始。

TXT、DOCX 爬取與保存

在爬取任何東西之前,我們都要先確認需要爬取的數據是不是異步加載的;如果是異步加載的直接爬取網頁是爬不到的。

要知道是不是異步加載其實很簡單,就用requests 對網頁發起請求,看看 response 是什么就可以了

url = 'https://wenku.baidu.com/view/4e29e5a730126edb6f1aff00bed5b9f3f90f72e7.html?rec_flag=default'
header = {'User-agent': 'Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
res = requests.get(url , headers = header)
res.text

教你用 Python 爬取 Baidu 文庫全格式文檔

 

很明顯,返回的東西,并不是我們所需要的內容; 根據常理來說,我們就可以認為該網頁是異步加載的。

但是,從常識來講,如果網頁的內容是異步加載的,那么直接通過百度搜索,是搜索不到網頁內部的內容的,但是很顯然,我們每次通過百度搜索都是可以直接找到文庫中的文本內容的。

如下:

教你用 Python 爬取 Baidu 文庫全格式文檔

 

那么這就有意思了,明明直接發起請求是獲取不到網頁內容的,但是為什么通過百度搜索就可以找到呢? 關鍵肯定在于百度搜索 上面。

這個時候通過查閱資料,我們了解到,最主要的問題出在我們的 headers

在爬取網頁時,headers 通常是作為身份證,讓網頁不看出我們是爬蟲;如果不加 headers,網頁直接就會看出我們是爬蟲,就會拒絕訪問

教你用 Python 爬取 Baidu 文庫全格式文檔

 

再深入了解一下 headers 的識別機理,我們發現了叫做 Robot 協議的東西。

它規定了什么樣的 headers 可以訪問網頁內部內容,除了指定 headers 之外的 headers,都是無法請求頁面內容的。

比如說百度文庫的 Robot 協議就是下面這樣的:

User-agent: Baiduspider

Disallow: /w?

Disallow: /search?

Disallow: /submit

Disallow: /upload

Disallow: /cashier/   

而我們需要爬取的內容 url 格式為

https://wenku.baidu.com/view/?.html

這代表 Baiduspider 應該可以爬取文庫內容;大致猜測這是因為百度搜索時需要根據文本內容匹配搜索選項,所以放行。

因此我們嘗試偽裝 UA 為 Baiduspider

url = 'https://wenku.baidu.com/view/4e29e5a730126edb6f1aff00bed5b9f3f90f72e7.html?rec_flag=default'
header = {'User-agent': 'googlebot'}
res = requests.get(url , headers = header)
res.text

果然不出所料,我們成功地獲取到了目標內容

教你用 Python 爬取 Baidu 文庫全格式文檔

 

既然已經成功獲取到了網頁的正確源代碼,那么下一步就是去解析網頁獲取內容。

解析網頁源代碼的庫有很多,這里我們使用 BeautifulSoup

plist = []
soup = BeautifulSoup(r, "html.parser")
plist.append(soup.title.string)
for div in soup.find_all('div', attrs={"class": "bd doc-reader"}):
    plist.extend(div.get_text().split('n'))
plist = [c.replace(' ', '') for c in plist]
plist = [c.replace('\x0c', '') for c in plist]
plist

整個解析是非常容易的,都是很標準的操作。

在這里就不多加敘述了,最終的效果如下:

教你用 Python 爬取 Baidu 文庫全格式文檔

 

當然爬取到東西了只是萬里長征的第一步,就這樣是肯定不行的,我們還需要將爬取的內容保存起來,通常是保存為 txt 文件

file = open('test.txt', 'w',encoding='utf-8')
for str in plist:
    file.write(str)
    file.write('n')
file.close()
教你用 Python 爬取 Baidu 文庫全格式文檔

 

但是為了美觀起見,我們在這里選擇使用 python-docx 庫將內容保存為 docx 文件

with open('test.txt', encoding='utf-8') as f:
    docu = Document()
    docu.add_paragraph(f.read())
    docu.save('test.docx')
教你用 Python 爬取 Baidu 文庫全格式文檔

 

PPT、PDF 爬取與保存

教你用 Python 爬取 Baidu 文庫全格式文檔

 

有了之前的經驗教訓,在爬取的時候我們首先就嘗試了使用爬取 TXT、DOCX 的方法,嘗試是否可以爬到內容

url = 'https://wenku.baidu.com/view/a4ac1b57dd88d0d232d46a0f.html?fr=search'
header = {'User-agent': 'Googlebot'}
res = requests.get(url , headers = header)
res.text

很可惜的是,我們并沒有訪問到

原因仔細想想也很簡單,在百度搜索的時候,直接搜索是搜不到 PPT 或者 PDF 的內容的

教你用 Python 爬取 Baidu 文庫全格式文檔

 

那么很顯然,PPT 和 PDF 是通過異步的方法進行內容加載的

對待異步加載的數據,我們通常采取的策略有兩種

1、第一個就是直接找到發起異步請求的接口,自己構造請求頭,發起請求

2、第二個就是通過 Selenium 這樣的自動化測試工具去爬取

教你用 Python 爬取 Baidu 文庫全格式文檔

 

百度文庫的接口太難找了,請求頭的構造也很麻煩,找了很久也沒有很滿意。

所以在本次爬取中,我們使用的是第二種方法,使用 Selenium 這樣的自動化測試工具

教你用 Python 爬取 Baidu 文庫全格式文檔

 

這里我們需要下載 ChromeDriver 這個插件,當然這里是默認大家使用的是 Chrome 瀏覽器,如果是其他的瀏覽器,firefox,safari 等等,直接去網上找到相應 Driver 就可以了。

這里給出 ChromeDriver 的下載地址

http://npm.taobao.org/mirrors/chromedriver/

大家一定要下載和自己 Chrome 瀏覽器版本一致的 ChromeDriver,不然程序是運行會報錯

教你用 Python 爬取 Baidu 文庫全格式文檔

 

我們先不急著馬上開始爬取,我們先來嘗試使用一下Selenium調用ChromeDriver

import requests
from selenium import webdriver
url = 'https://wenku.baidu.com/view/5292b2bc0166f5335a8102d276a20029bd64638c.html?fr=search'
driver = webdriver.Chrome(r'F:driverchromedriver.exe')
driver.get(url)

怎么樣,是不是瀏覽器自動打開了? 現在我們嘗試輸出這個 driver,就可以看見,網頁的正確源代碼已經在里面了

現在我們仔細研究一下源代碼就可以看到,我們需要的內容在下面這個位置

教你用 Python 爬取 Baidu 文庫全格式文檔

 

現在正確的源代碼也有了,內容的位置也知道了,直接解析,爬取,完事就好了。

教你用 Python 爬取 Baidu 文庫全格式文檔

 

想得美,經過這樣的爬取之后,對內容進行解析,讓我們看看究竟爬到沒有

教你用 Python 爬取 Baidu 文庫全格式文檔

 

from lxml import etree
import re
html=etree.HTML(driver.page_source)
links=html.xpath("//div[@class='reader-pic-item']/@style")
part = re.compile(r'url[(](.*?)[)]')
qa="".join(links)
z=part.findall(qa)
z
教你用 Python 爬取 Baidu 文庫全格式文檔

 

我們可以知道,其實我們只爬到 3 張 PDF,其他的都沒有爬到。

這是為什么呢?

這是百度文庫為了防止大家去爬,專門設置的一個小機關

教你用 Python 爬取 Baidu 文庫全格式文檔

 

返回百度文庫,我們仔細看看源代碼,其實我們可以發現,隨著頁面的變化,源代碼是不斷改變的,每次都只有 3 張圖片的 url。

并且這個頁碼數也有一定的規律,如果在第二頁,那么圖片就是 1,2,3,如果在第三頁,圖片就是 2,3,4

教你用 Python 爬取 Baidu 文庫全格式文檔

 

那么我們的疑惑一下就解決了,只需要不斷地進行換頁的爬取,就可以了

接下來就是如何實現換頁的操作了

這個需要兩個步驟,先是點擊繼續閱讀,然后進行頁面輸入實現換頁。

先實現點擊的操作,代碼如下:

button = driver.find_element_by_xpath("//*[@id='html-reader-go-more']/div[2]/div[1]/span")
button.click()
driver.execute_script("arguments[0].click();", button)

整個操作是通過 JS 來進行的,大家可以把這個記住,以后需要點擊的時候直接用就可以

然后就是輸入頁面實現換頁,這個其實涉及的比較多,細分的話,步驟分為獲取總頁數,依次輸入頁面并點擊。

import re
# 尋找頁面
source = re.compile(r'<span class="page-count">/(.*?)</span>')
number = int(source.findall(driver.page_source)[0])
# 輸入頁面并點擊
driver.find_element_by_class_name("page-input").clear()
driver.find_element_by_class_name("page-input").send_keys('2')
driver.find_element_by_class_name("page-input").send_keys(Keys.ENTER)

如果小伙伴成功實現了上面的操作,其實大體的爬取工作已經差不多了,接下來就是保存我們的 PPT 和 PDF了

教你用 Python 爬取 Baidu 文庫全格式文檔

 

因為爬取 PDF 和 PPT 的時候,我們是爬取的圖片的源地址,那么我們要獲得這張圖片并保存下來就必須對這個地址發起請求,然后將返回頭以二進制保存下來。

for m in range(3):
    pic = requests.get(z[m]).content
    # 方法一
#     file = open(f'./照片/{m+1}.jpg','wb')
#     file.write(pic)
#     file.close()
    # 方法二
    with open(f'./照片/{m+1}.jpg','wb') as f:
        f.write(pic)
        f.close()

在這里,提醒大家一下一定要按照對圖片用正確順序進行命名,因為后面保存為 PDF 的時候,需要排序

在 py 文件的目錄下,大家就可以看見保存下來的圖片了

最后一步,將圖片保存為 PDF

from PIL import Image
import os
folderPath = "F:/TEST"
filename = "test"
files = os.listdir(folderPath)
jpgFiles = []
sources = []
for file in files:
    if 'jpg' in file:
        jpgFiles.append(file)
tep = []
for i in jpgFiles:
    ex = i.split('.')
    tep.append(int(ex[0]))
tep.sort()
jpgFiles=[folderPath +'/'+ str(i) + '.jpg' for i in tep]
output = Image.open(jpgFiles[0])
jpgFiles.pop(0)
for file in jpgFiles:
   img = Image.open(file)
   img = img.convert("P")
   sources.append(img)
output.save(f"./{filename}.pdf","PDF",save_all=True,append_images=sources)

最終的結果就是生成了咱們的 PDF 文件

教你用 Python 爬取 Baidu 文庫全格式文檔

 

上述的操作看起來很多,很麻煩,其實并不是的,因為大部分的操作都是固定的,大家只需要記熟就可以了。

簡單的 GUI 制作

教你用 Python 爬取 Baidu 文庫全格式文檔

 

GUI 這塊,我們整了點新活兒,用 C# 編寫 winform 簡易的 GUI,調用爬蟲的 Py thon 代碼

教你用 Python 爬取 Baidu 文庫全格式文檔

 

C# 調用 python 項目的方式我簡單用 Process 類執行,通過執行 python.exe 執行代碼

public static void RunPythonScript(string sArgName, string py, string args = "", params string[] teps)
{
    Process p = new Process();

    //(沒放debug下,寫絕對路徑)
    //string path = @"C:UserszllDesktopbaiduCSharpCallPythonbinDebug" + sArgName;
    // 獲得python文件的絕對路徑(將文件放在c#的debug文件夾中可以這樣操作)
    string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + sArgName;

    //沒有配環境變量的話,可以像我這樣寫python.exe的絕對路徑。如果配了,直接寫"python.exe"即可
    //p.StartInfo.FileName = @"C:UserszllAppDataLocalProgramsPythonPython37-32python.exe";
    p.StartInfo.FileName = @py;
    string sArguments = path;

    foreach (string sigstr in teps)
    {
        sArguments += " " + sigstr;//傳遞參數
    }

    sArguments += " " + args;

    p.StartInfo.Arguments = sArguments;
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardInput = true;
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.CreateNoWindow = true;

    p.Start();
    p.BeginOutputReadLine();
    p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
    Console.ReadLine();
    p.WaitForExit();
}

對輸入 的內容進行簡單判斷,如果不是百度文庫地址或不是 python.exe 地址,報錯

if (!url.Contains("https://wenku.baidu.com/view/"))
{
    MessageBox.Show("請輸入正確的百度文庫網址!");
    lbl_state.Text = "請重新輸入。";
}
else if (!py.Contains("python.exe"))
{
    MessageBox.Show("請輸入正確的python.exe路徑!");
    lbl_state.Text = "請重新輸入。";
}
else
{
    //輸入參數列表
    String[] strArr = new String[] { url, istxt };
    string sArguments = @"srcwenku.py";//這里是python的文件名字
    RunPythonScript(sArguments, py, "-u", strArr);
    if(result.Contains("0"))
        lbl_state.Text = "對不起,爬取失敗。";
    else if (result.Contains("1"))
        lbl_state.Text = "爬取成功!";
}

因為 GUI 部分比較簡單,這里就不過多描述了。

分享到:
標簽:Python
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定