1. 程式人生 > >Python爬取Python教程並製作成pdf

Python爬取Python教程並製作成pdf

想要把教程變成PDF有三步:

1、先生成空html,爬取每一篇教程放進一個新生成的div,這樣就生成了包含所有教程的html檔案(BeautifulSoup)

2、將html轉換成pdf(wkhtmltopdf)

3、由於反爬做的比較好,在爬取的過程中還需要代理ip(免費 or 付費)

推薦下我自己建立的Python學習交流群960410445,這是Python學習交流的地方,不管你是小白還是大牛,小編都歡迎,不定期分享乾貨,包括我整理的一份適合零基礎學習Python的資料和入門教程。

開始使用

將一段文件傳入 BeautifulSoup 的構造方法,就能得到一個文件的物件, 可以傳入一段字串或一個檔案控制代碼.

如下所示:


首先,文件被轉換成Unicode,並且HTML的例項都被轉換成Unicode編碼.

然後,Beautiful Soup選擇最合適的解析器來解析這段文件,如果手動指定解析器那麼Beautiful Soup會選擇指定的解析器來解析文件.

物件的種類

Beautiful Soup 將複雜 HTML 文件轉換成一個複雜的樹形結構,每個節點都是 Python 物件,所有物件可以歸納為 4 種: Tag , NavigableString , BeautifulSoup , Comment .

Tag:通俗點講就是 HTML 中的一個個標籤,類似 div,p。

NavigableString:獲取標籤內部的文字,如,soup.p.string。

BeautifulSoup:表示一個文件的全部內容。

Comment:Comment 物件是一個特殊型別的 NavigableString 物件,其輸出的內容不包括註釋符號.

Tag

Tag就是html中的一個標籤,用BeautifulSoup就能解析出來Tag的具體內容,具體的格式為soup.name,其中name是html下的標籤,具體例項如下:

print soup.title輸出title標籤下的內容,包括此標籤,這個將會輸出

 

print soup.head輸出head標籤下的內容

 

如果 Tag 物件要獲取的標籤有多個的話,它只會返回所以內容中第一個符合要求的標籤

Tag 屬性

每個 Tag 有兩個重要的屬性 name 和 attrs:

name:對於Tag,它的name就是其本身,如soup.p.name就是p

attrs是一個字典型別的,對應的是屬性-值,如print soup.p.attrs,輸出的就是{'class': ['title'], 'name': 'dromouse'},當然你也可以得到具體的值,如print soup.p.attrs['class'],輸出的就是[title]是一個列表的型別,因為一個屬性可能對應多個值,當然你也可以通過get方法得到屬性的,如:print soup.p.get('class')。還可以直接使用print soup.p['class']

get

get方法用於得到標籤下的屬性值,注意這是一個重要的方法,在許多場合都能用到,比如你要得到<img src="#">標籤下的影象url,那麼就可以用soup.img.get('src'),具體解析如下:

# 得到第一個p標籤下的src屬性printsoup.p.get("class")

string

得到標籤下的文字內容,只有在此標籤下沒有子標籤,或者只有一個子標籤的情況下才能返回其中的內容,否則返回的是None具體例項如下:

# 在上面的一段文字中p標籤沒有子標籤,因此能夠正確返回文字的內容printsoup.p.string# 這裡得到的就是None,因為這裡的html中有很多的子標籤printsoup.html.string

get_text()

可以獲得一個標籤中的所有文字內容,包括子孫節點的內容,這是最常用的方法

搜尋文件樹

BeautifulSoup 主要用來遍歷子節點及子節點的屬性,通過Tag取屬性的方式只能獲得當前文件中的第一個 tag,例如,soup.p。如果想要得到所有的<p> 標籤,或是通過名字得到比一個 tag 更多的內容的時候,就需要用到 find_all()

find_all(name, attrs, recursive, text, **kwargs )

find_all是用於搜尋節點中所有符合過濾條件的節點。

name引數:是Tag的名字,如p,div,title

# 1. 節點名print(soup.find_all('p'))# 2. 正則表示式print(soup.find_all(re.compile('^p')))# 3. 列表  print(soup.find_all(['p','a']))

另外 attrs 引數可以也作為過濾條件來獲取內容,而 limit 引數是限制返回的條數。

CSS 選擇器

以 CSS 語法為匹配標準找到 Tag。同樣也是使用到一個函式,該函式為select(),返回型別是 list。它的具體用法如下:

# 1. 通過 tag 標籤查詢print(soup.select(head))# 2. 通過 id 查詢print(soup.select('#link1'))# 3. 通過 class 查詢print(soup.select('.sister'))# 4. 通過屬性查詢print(soup.select('p[name=dromouse]'))# 5. 組合查詢print(soup.select("body p"))

wkhtmltopdf

wkhtmltopdf主要用於HTML生成PDF。

pdfkit是基於wkhtmltopdf的python封裝,支援URL,本地檔案,文字內容到PDF的轉換,其最終還是呼叫wkhtmltopdf命令。

安裝

先安裝wkhtmltopdf,再安裝pdfkit。

https://wkhtmltopdf.org/downloads.html

pdfkit

shell pip3 install pdfkit

轉換url/file/string

importpdfkitpdfkit.from_url('http://google.com','out.pdf')pdfkit.from_file('index.html','out.pdf')pdfkit.from_string('Hello!','out.pdf')

轉換url或者檔名列表

pdfkit.from_url(['google.com','baidu.com'],'out.pdf')pdfkit.from_file(['file1.html','file2.html'],'out.pdf')

轉換開啟檔案

withopen('file.html')asf:    pdfkit.from_file(f,'out.pdf')

自定義設定


使用代理ip

爬取十幾篇教程之後觸發了這個錯誤:

看來廖大的反爬蟲做的很好,於是只好使用代理ip了,嘗試了免費的西刺免費代理後,最後選擇了付費的 阿布雲 ,感覺響應速度和穩定性還OK。

執行結果

執行過程截圖:

執行過程

生成的效果圖:

效果圖

程式碼如下: