2016-04-18 36 views
1

我正在嘗試讀取網頁並將格式化文本輸出到文本文件。下面的代碼使用格式打印到shell,但是當我將它寫入文件時,它將它放在一行上(文本中出現換行符/ n)。與生成的文本文件相比,爲什麼Python 3 shell中的文本格式不同?

我嘗試了各種各樣的東西,如不將它轉換爲字符串,使用從美麗的湯美容但沒有似乎產生格式文本文件。我假設我錯過了一些相當基本的東西。任何幫助或指導將不勝感激。

# Import 
from urllib.request import urlopen 
from bs4 import BeautifulSoup 

#The actual code 


URL = "https://simple.wikipedia.org/wiki/castle" #The target URL 
html = urlopen(URL).read() # Reads the url to variable html 
soup = BeautifulSoup(html, "lxml") # Uses BS4 to create the soup using the lxml parser 
soup = soup.get_text() # Extracts the text 
print(soup) # Prints to python 3.5.1 shell, formatted as I would expect 


# Now writing what I have extracted to a text file 
file = open("TextOutput.txt", 'w') # Creates the file and opens as write (w) 
file.writelines(str(soup.encode('UTF-8'))) # Tried file.write/lines(soup), convertion to string and encoding as UTF-8 needed to avoid errors 
file.close() 

文件輸出的一個例子是這樣的:

B'\ n \ n \ nCastle - 簡單的英文維基百科,自由的百科全書\ ndocument.documentElement.className = document.documentElement.className .replace(/(^ | \ s)client-nojs(\ s | $)/,「$ 1client-js $ 2」); \ n(window.RLQ = window.RLQ || [])。push(function ){mw.config.set({ 「wgCanonicalNamespace」: 「」, 「wgCanonicalSpecialPageName」:假 「wgNamespaceNumber」:0 「wgPageName」: 「城堡」, 「wgTitle」: 「城堡」, 「wgCurRevisionId」:5333370, 「wgRevisionId」:5333370「wgArticleId」:15933「wgIsArticle」:true,「wgIsRedirect」:false,「wgAction」:「view」,「wgUserName」:null,「wgUserGroups」:[「」], wgCategories 「:」 城堡 「],」 wgBreakFrames 「:假的,」 wgPageContentLanguage 「:」 恩」, 「wgPageContentModel」: 「wikitext的」, 「wgSeparatorTransformTable」: 「」, 「」], 「wgDigitTransformTable」: 「」 「」], 「wgDefaultDateFormat」: 「日月」, 「wgMonthNames」: 「」, 「月」, 「日」, 「月」, 「月」, 「五一」, 「六一」, 「七一」,」八五 「 」九五「, 」十月「, 」月「, 」月「], 」wgMonthNamesShort「: 」「, 」月「, 」月「, 」月「, 」月「, 」月「,」 君「 」月「, 」月「, 」月「, 」月「, 」月「, 」月「], 」wgRelevantPageName「: 」青山「, 」wgRelevantArticleId「:15933, 」wgRequestId「: 」VxUR5gpAIDAAAEXY6FMAAACC「,」 wgIsProbablyEditable 「:真實的,」 wgRestrictionEdit 「:[],」 wgRestrictionMove 「:[],」 wgWikiEditorEnabledModules 「:{」 工具欄 「:真正的」 對話 「:真正的」 預覽 「:假的,」 出版 「:假},」 wgBetaFeaturesFeatures 「:[],」 wgMediaViewerOnClick 「:真」 wgMediaViewerEnabledByDefault 「:真」 wgVisualEditor 「:{」 pageLanguageCode 「:」 EN」, 「pageLanguageDir」: 「LTR」, 「usePageImages」:真 「usePageDescriptions」:真}, 「wgPreferredVariant」: 「恩」, 「wgRelatedArticles」:空, 「wgRelatedArticlesUseCirrusSearch」:真實的,「WG RelatedArticlesOnlyUseCirrusSearch 「:假」 wgULSAcceptLanguageList 「:[],」 wgULSCurrentAutonym 「:」 英語 「 」wgCategoryTreePageCategoryOptions「: 」{\「 模式\ 」:0,\「 hideprefix \ 」:20,\「 showcount \」:真, \ 「命名空間\」:假}」, 「wgNoticeProject」: 「維基百科」, 「wgCentralNoticeCategoriesUsingLegacy」:[ 「籌款」, 「籌款」], 「wgCentralAuthMobileDomain」:假 「wgWikibaseItemId」: 「Q23413」, 「wgVisualEditorToolbarScrollOffset」: 0}); mw.loader.implement( 「user.options」,功能($,jQuery的){mw.user.options.set({ 「變體」: 「EN」});}); mw.loader.implement (「user.tokens」,函數($,jQuery){\ nmw.user.tokens.set({「editToken」:「+ \\」,「patrolToken」:「+ \\」,「watchToken」:「 \\「,」csrfToken「:」+ \\「});/ @nomin * /; \ n \ n}); mw.loader.load([」mw.MediaWikiPlayer.loader「,」mw.PopUpMediaTransform「 「mw.TMHGalleryHook.js」, 「mediawiki.page.startup」, 「mediawiki.legacy.wikibits」, 「ext.centralauth.centralautologin」, 「mmv.head」, 「ext.visualEditor.desktopArticleTarget.init」,」 ext.uls.init 「 」ext.uls.interface「,」 ext.centralNot ice.bannerController」, 「skins.vector.js」]);}); \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ nCastle \ n \ n來自維基百科,自由的百科全書\ n \ n \ n \ t \ t \ t \ t \ t跳轉到:\ t \ \ t \ t \ t \ t導航,\ t \ t \ t \ t \ t搜索\ n \ n \ n \ n \ n \ n英國博迪安城堡被充滿水的護城河包圍。\ n \ n \ n \ n \ n \ n \ n利希滕斯坦城堡\ n \ n \ n一座城堡(來自拉丁詞「castellum」)是中世紀在歐洲和中東建造的一座堅固的建築。人們爭論城堡這個詞的含義。但是,它通常意味着貴族或貴族的私人結構。這不同於一個不是住宅的堡壘,也不是一個防禦性強的城鎮。大約900年前的城堡建成後,他們擁有許多不同的形狀和不同的細節。\ n城堡在9世紀和10世紀始於歐洲。他們控制着他們周圍的地方,可以幫助攻擊和防守。武器可以從城堡發射,或者可以保護城堡中的敵人。但是,城堡也是權力的象徵。他們可以用來控制周圍的人和道路。\ n許多城堡一開始經常使用體力勞動,用泥土和木頭建造,然後用石頭代替它們的防禦。早期的城堡通常使用自然保護,並沒有塔。在晚12和早期的13世紀,雖然,城堡變得更長,更復雜\ n

+0

是什麼,輸出什麼樣子的? – ShadowRanger

+0

http://stackoverflow.com/questions/13730107/writelines-writes-lines-without-newline-just-fills-the-file –

回答

1

file.writelines(str(soup.encode('UTF-8')))是怎麼樣的瘋狂,它是:

  1. 編碼文本(str)二進制(bytes
  2. str包裝獲得的該文本表示(所以它需要鍵入重新二進制字節的東西,但它不是原始的二進制)
  3. 寫作,在一個時間導致一個字符(writelines迭代你給它,而str s迭代字符)

步驟3是愚蠢和低效率,但大多是無害的。如果您將原始二進制文件寫入以二進制寫入打開的文件並且實際編寫了bytes對象,那麼步驟1將會很順利。但#1和#2一起意味着像新線那樣的東西在輸出中被轉換爲文字\n,而不是實際上打破了一條線。如é這樣的非ASCII字符輸出爲\xc3\xa9,整個事情被包裝在b''(或b"")中。

你想要的東西,如:

# open with UTF-8 encoding (in case your system defaults to something else) 
with open("TextOutput.txt", 'w', encoding='utf-8') as file: 
    # Get the text and write it as a single block 
    file.write(soup.get_text()) 
+0

它確實感到瘋狂。這產生了我所期望的,謝謝!我想我需要學習更多(我有一些像file.open和file.write開始 - 假設我需要不同的語法/ UTF-8編碼)。 – Tom

+0

@ user6217257:我猜你在使用Windows?在Windows上,默認編碼通常不是你想要的;它是一個特定於語言環境的ASCII超集(英文和許多西歐語言環境,['cp1252'](https://en.wikipedia.org/wiki/CP1252))。問題是,網頁大部分是UTF-8,在這種情況下,你所抓取的頁面有一個「↑」字符,它不會出現在CP1252中。如果沒有指定可以處理該問題的編碼(爲了獲得最大兼容性和工具友好性,通常需要UTF-8,或者在Windows或UTF-16上),那麼在嘗試編碼爲CP1252時會出錯。 – ShadowRanger

+0

我在Windows上,這是有趣的信息。這也是爲什麼通過在Windows中雙擊運行上述(修改後的腳本)失敗給出某種回溯錯誤?但不是當打印(湯)命令被刪除。 – Tom

相關問題