2016-01-24 54 views
1

我決定學習C++,我非常喜歡網站www.learncpp.com。 現在,我想製作一個pdf版本並打印出來,以便我可以在紙上閱讀它。首先,我已經構建了網站中所有章節的url收集器。它工作正常。如何知道什麼是正確的編碼?

現在我正在創建一個HTML的first chapter。我寫道:

import requests 
from bs4 import BeautifulSoup 
import codecs 

req = requests.get("http://www.learncpp.com/cpp-tutorial/01-introduction-to-these-tutorials/") 
soup = BeautifulSoup(req.text,'lxml') 

content = soup.find("div", class_="post-9") 

f = open("first_lesson.html","w") 
f.write(content.prettify().encode('utf-8')) 
f.close() 

,我得到了我的first_lesson.html文件的文件夾中。 問題是,當我打開html文件來檢查結果時,有奇怪的符號(嘗試運行代碼並查看)在這裏和那裏。

我加.encode('utf-8'),否則我會得到錯誤:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u2014' in position 155: ordinal not in range(128) 

如何消除這些怪異的符號?什麼是正確的編碼? 而且,如果我將來遇到類似的問題,我怎麼才能知道什麼是正確的編碼?

UPDATE:代替'utf-8'編碼我在'windows-1252'編碼,它的工作。但是理解如何正確編碼的最佳策略是什麼?因爲我不認爲試試這個試試這是一個很好的

+0

爲什麼不能http://scrapy.org/?它的開發正是爲了這樣的任務。 –

+0

@CodePainters,req和bs4是我被教會颳去的第一種方式。我很樂意學習新的方法(我絕對想看看scrapy),但現在我想明白爲什麼這不起作用 – Pigna

回答

0

content.prettify()是一個unicode字符串。它恰好包含了映射到角色的代碼點U + 2014(EM DASH)。因爲8212 = 0x2014大於127.

但是,您可以使用任何可以處理unicode代碼點的編碼來編碼您的unicode字符串,例如utf-16,utf-32,ucs-2 ,ucs-4或ucs-8。沒有「正確的」編碼,但是utf-8是他們的王者,所以當你想編碼一個unicode字符串時,通常它是一個不錯的選擇,但你可以選擇另一個(python支持)和你的程序會 - 例如 - 也

f.write(content.prettify().encode('utf-16')) 

prettify工作給你一個unicode字符串和每默認嘗試使用UTF-8解碼(這是我的理解從具有看看源),但你可以給prettify一個明確的編碼作爲參數。將unicode字符串想象成一個抽象,一系列unicode代碼點基本上對應於一系列字符(它們只是小圖像)。

如果您需要使用beautifulsoup查找HTML文檔的內容類型,您可能會發現thisthis問題有用。另一點:一般來說,只要你有明文字節,沒有人告訴你他們應該如何解碼,你是運氣不好,必須打鼴鼠。如果你知道你正在處理文本,utf-8通常是一個很好的初步猜測,因爲它是a)廣泛使用的,b)前128個unicode字符與ASCII一一對應,utf-8對它們進行編碼相同的字節值。

您可能還會發現this chartablethis來自PyCon 2012的演講很有用。

1

使用python2請求,你應該使用.content讓請求採取編碼的照顧,你可以使用io.open寫入文件:

import requests 
from bs4 import BeautifulSoup 
import io 


req = requests.get("http://www.learncpp.com/cpp-tutorial/01-introduction-to-these-tutorials/") 
soup = BeautifulSoup(req.content, 'lxml') 
content = soup.find("div", class_="post-9") 

with io.open("first_lesson.html", "w") as f: 
    f.write(soup.prettify()) 

如果你確實想指定編碼,美化需要一個編碼參數soup.prettify(encoding=...),也有編碼屬性:

enc = req.encoding 

您可以分析嘗試cgi.parse_headers解析頭:

import cgi 

enc = cgi.parse_header(req.headers.get('content-type', ""))[1]["charset"] 

或嘗試安裝和使用chardet模塊:

import chardet 

enc = chardet.detect(req.content) 

你也應該知道,許多編碼可以運行沒有錯誤,但你最終會與文件中的垃圾。 charset設置爲utf-8,你可以在返回的頭文件中看到它,如果你看看源代碼,你可以看到<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

相關問題