使用 bs4 和请求处理后如何正确打印出 unicode 文本? [复制]

Posted

技术标签:

【中文标题】使用 bs4 和请求处理后如何正确打印出 unicode 文本? [复制]【英文标题】:How to properly print out unicode text after processing with bs4 and requests? [duplicate] 【发布时间】:2013-09-22 10:10:40 【问题描述】:

我正在尝试创建一个包含 Torah 整个文本的 txt 单个文件。 我可以在 google 上找到的最佳来源是:http://www.mechon-mamre.org/i/t/t0101.htm。

这给了我必须连接并写入文件的章节。

在运行以下脚本时使用 urxvt(支持 unicode 的终端)会出现乱码:

import requests
from bs4 import BeautifulSoup

url = 'http://www.mechon-mamre.org/i/t/t0101.htm'
response = requests.get(url)
soup = BeautifulSoup(response.text)
paragraphs = soup.find_all('p')

print paragraphs[1]

输出:

<p><b>à</b> <big>áÌÀ</big>øÅàùÑÄéú, áÌÈøÈà àÁìÉäÄéí, àÅú äÇùÌÑÈîÇéÄí, åÀàÅú äÈàÈøÆõ. 
<a name="2"> </a>
<b>á</b> åÀäÈàÈøÆõ, äÈéÀúÈä úÉäåÌ åÈáÉäåÌ, åÀçÉùÑÆêÀ, òÇì-ôÌÀðÅé úÀäåÉí; åÀøåÌçÇ àÁìÉäÄéí, îÀøÇçÆôÆú òÇì-ôÌÀðÅé äÇîÌÈéÄí. 
.....

我试图强制输出默认使用 unicode,但我得到了完全相同的输出:

print unicode(paragraphs[1])

BeautfulSoup 和 Python-Requests 都声称可以处理 unicode,所以问题可能出在我的代码上。如果我将浏览器中的希伯来文文本手动粘贴到 urxvt,我会得到真正的希伯来文。因此终端不是问题。

【问题讨论】:

您要打印到什么位置?如果是 Windows 命令提示符你还不如现在放弃。 @bobince,我在问题中提到了 urxvt。 啊,好的。好吧,上面是 cp1255 希伯来语被误解为 ISO-8859-1。不幸的是,您上面链接的页面未能在Content-Type 标头中指定charset,因此requests 模块无法知道它是什么编码,并猜测错误;真正的浏览器也经常猜错。我认为在请求中,如果您覆盖 response.encoding='cp1255',这应该会适当地更改您从 response.text 返回的内容。 【参考方案1】:

服务器没有报告内容的编码,requests(或者更确切地说是chardet)错误地猜测了内容编码。

改用原始字节

>>> soup = BeautifulSoup(response.content)
>>> paragraphs = soup.find_all('p')
>>> print paragraphs[1]
<p><b>א</b> <big>בְּ</big>רֵאשִׁית, בָּרָא אֱלֹהִים, אֵת הַשָּׁמַיִם, וְאֵת הָאָרֶץ. 
<a name="2"> </a>
<b>ב</b> וְהָאָרֶץ, הָיְתָה תֹהוּ וָבֹהוּ, וְחֹשֶׁךְ, עַל-פְּנֵי תְהוֹם; וְרוּחַ אֱלֹהִים, מְרַחֶפֶת עַל-פְּנֵי הַמָּיִם. 
<a name="3"> </a>
<b>ג</b> וַיֹּאמֶר אֱלֹהִים, יְהִי אוֹר; וַיְהִי-אוֹר. 
<a name="4"> </a>
<b>ד</b> וַיַּרְא אֱלֹהִים אֶת-הָאוֹר, כִּי-טוֹב; וַיַּבְדֵּל אֱלֹהִים, בֵּין הָאוֹר וּבֵין הַחֹשֶׁךְ. 
<a name="5"> </a>
<b>ה</b> וַיִּקְרָא אֱלֹהִים לָאוֹר יוֹם, וְלַחֹשֶׁךְ קָרָא לָיְלָה; וַיְהִי-עֶרֶב וַיְהִי-בֹקֶר, יוֹם אֶחָד.  פ<br/>
<a name="6"> </a>
<b>ו</b> וַיֹּאמֶר אֱלֹהִים, יְהִי רָקִיעַ בְּתוֹךְ הַמָּיִם, וִיהִי מַבְדִּיל, בֵּין מַיִם לָמָיִם. 
<a name="7"> </a>
<b>ז</b> וַיַּעַשׂ אֱלֹהִים, אֶת-הָרָקִיעַ, וַיַּבְדֵּל בֵּין הַמַּיִם אֲשֶׁר מִתַּחַת לָרָקִיעַ, וּבֵין הַמַּיִם אֲשֶׁר מֵעַל לָרָקִיעַ; וַיְהִי-כֵן. 
<a name="8"> </a>
<b>ח</b> וַיִּקְרָא אֱלֹהִים לָרָקִיעַ, שָׁמָיִם; וַיְהִי-עֶרֶב וַיְהִי-בֹקֶר, יוֹם שֵׁנִי.  פ<br/>
<a name="9"> </a>
<b>ט</b> וַיֹּאמֶר אֱלֹהִים, יִקָּווּ הַמַּיִם מִתַּחַת הַשָּׁמַיִם אֶל-מָקוֹם אֶחָד, וְתֵרָאֶה, הַיַּבָּשָׁה; וַיְהִי-כֵן. 
<a name="10"> </a>
<b>י</b> וַיִּקְרָא אֱלֹהִים לַיַּבָּשָׁה אֶרֶץ, וּלְמִקְוֵה הַמַּיִם קָרָא יַמִּים; וַיַּרְא אֱלֹהִים, כִּי-טוֹב. 
<a name="11"> </a>
<b>יא</b> וַיֹּאמֶר אֱלֹהִים, תַּדְשֵׁא הָאָרֶץ דֶּשֶׁא עֵשֶׂב מַזְרִיעַ זֶרַע, עֵץ פְּרִי עֹשֶׂה פְּרִי לְמִינוֹ, אֲשֶׁר זַרְעוֹ-בוֹ עַל-הָאָרֶץ; וַיְהִי-כֵן. 
<a name="12"> </a>
<b>יב</b> וַתּוֹצֵא הָאָרֶץ דֶּשֶׁא עֵשֶׂב מַזְרִיעַ זֶרַע, לְמִינֵהוּ, וְעֵץ עֹשֶׂה-פְּרִי אֲשֶׁר זַרְעוֹ-בוֹ, לְמִינֵהוּ; וַיַּרְא אֱלֹהִים, כִּי-טוֹב. 
<a name="13"> </a>
<b>יג</b> וַיְהִי-עֶרֶב וַיְהִי-בֹקֶר, יוֹם שְׁלִישִׁי.  פ<br/>
<a name="14"> </a>
<b>יד</b> וַיֹּאמֶר אֱלֹהִים, יְהִי מְאֹרֹת בִּרְקִיעַ הַשָּׁמַיִם, לְהַבְדִּיל, בֵּין הַיּוֹם וּבֵין הַלָּיְלָה; וְהָיוּ לְאֹתֹת וּלְמוֹעֲדִים, וּלְיָמִים וְשָׁנִים. 
<a name="15"> </a>
<b>טו</b> וְהָיוּ לִמְאוֹרֹת בִּרְקִיעַ הַשָּׁמַיִם, לְהָאִיר עַל-הָאָרֶץ; וַיְהִי-כֵן. 
<a name="16"> </a>
<b>טז</b> וַיַּעַשׂ אֱלֹהִים, אֶת-שְׁנֵי הַמְּאֹרֹת הַגְּדֹלִים:  אֶת-הַמָּאוֹר הַגָּדֹל, לְמֶמְשֶׁלֶת הַיּוֹם, וְאֶת-הַמָּאוֹר הַקָּטֹן לְמֶמְשֶׁלֶת הַלַּיְלָה, וְאֵת הַכּוֹכָבִים. 
<a name="17"> </a>
<b>יז</b> וַיִּתֵּן אֹתָם אֱלֹהִים, בִּרְקִיעַ הַשָּׁמָיִם, לְהָאִיר, עַל-הָאָרֶץ. 
<a name="18"> </a>
<b>יח</b> וְלִמְשֹׁל, בַּיּוֹם וּבַלַּיְלָה, וּלְהַבְדִּיל, בֵּין הָאוֹר וּבֵין הַחֹשֶׁךְ; וַיַּרְא אֱלֹהִים, כִּי-טוֹב. 
<a name="19"> </a>
<b>יט</b> וַיְהִי-עֶרֶב וַיְהִי-בֹקֶר, יוֹם רְבִיעִי.  פ<br/>
<a name="20"> </a>
<b>כ</b> וַיֹּאמֶר אֱלֹהִים--יִשְׁרְצוּ הַמַּיִם, שֶׁרֶץ נֶפֶשׁ חַיָּה; וְעוֹף יְעוֹפֵף עַל-הָאָרֶץ, עַל-פְּנֵי רְקִיעַ הַשָּׁמָיִם. 
<a name="21"> </a>
<b>כא</b> וַיִּבְרָא אֱלֹהִים, אֶת-הַתַּנִּינִם הַגְּדֹלִים; וְאֵת כָּל-נֶפֶשׁ הַחַיָּה הָרֹמֶשֶׂת אֲשֶׁר שָׁרְצוּ הַמַּיִם לְמִינֵהֶם, וְאֵת כָּל-עוֹף כָּנָף לְמִינֵהוּ, וַיַּרְא אֱלֹהִים, כִּי-טוֹב. 
<a name="22"> </a>
<b>כב</b> וַיְבָרֶךְ אֹתָם אֱלֹהִים, לֵאמֹר:  פְּרוּ וּרְבוּ, וּמִלְאוּ אֶת-הַמַּיִם בַּיַּמִּים, וְהָעוֹף, יִרֶב בָּאָרֶץ. 
<a name="23"> </a>
<b>כג</b> וַיְהִי-עֶרֶב וַיְהִי-בֹקֶר, יוֹם חֲמִישִׁי.  פ<br/>
<a name="24"> </a>
<b>כד</b> וַיֹּאמֶר אֱלֹהִים, תּוֹצֵא הָאָרֶץ נֶפֶשׁ חַיָּה לְמִינָהּ, בְּהֵמָה וָרֶמֶשׂ וְחַיְתוֹ-אֶרֶץ, לְמִינָהּ; וַיְהִי-כֵן. 
<a name="25"> </a>
<b>כה</b> וַיַּעַשׂ אֱלֹהִים אֶת-חַיַּת הָאָרֶץ לְמִינָהּ, וְאֶת-הַבְּהֵמָה לְמִינָהּ, וְאֵת כָּל-רֶמֶשׂ הָאֲדָמָה, לְמִינֵהוּ; וַיַּרְא אֱלֹהִים, כִּי-טוֹב. 
<a name="26"> </a>
<b>כו</b> וַיֹּאמֶר אֱלֹהִים, נַעֲשֶׂה אָדָם בְּצַלְמֵנוּ כִּדְמוּתֵנוּ; וְיִרְדּוּ בִדְגַת הַיָּם וּבְעוֹף הַשָּׁמַיִם, וּבַבְּהֵמָה וּבְכָל-הָאָרֶץ, וּבְכָל-הָרֶמֶשׂ, הָרֹמֵשׂ עַל-הָאָרֶץ. 
<a name="27"> </a>
<b>כז</b> וַיִּבְרָא אֱלֹהִים אֶת-הָאָדָם בְּצַלְמוֹ, בְּצֶלֶם אֱלֹהִים בָּרָא אֹתוֹ:  זָכָר וּנְקֵבָה, בָּרָא אֹתָם. 
<a name="28"> </a>
<b>כח</b> וַיְבָרֶךְ אֹתָם, אֱלֹהִים, וַיֹּאמֶר לָהֶם אֱלֹהִים פְּרוּ וּרְבוּ וּמִלְאוּ אֶת-הָאָרֶץ, וְכִבְשֻׁהָ; וּרְדוּ בִּדְגַת הַיָּם, וּבְעוֹף הַשָּׁמַיִם, וּבְכָל-חַיָּה, הָרֹמֶשֶׂת עַל-הָאָרֶץ. 
<a name="29"> </a>
<b>כט</b> וַיֹּאמֶר אֱלֹהִים, הִנֵּה נָתַתִּי לָכֶם אֶת-כָּל-עֵשֶׂב זֹרֵעַ זֶרַע אֲשֶׁר עַל-פְּנֵי כָל-הָאָרֶץ, וְאֶת-כָּל-הָעֵץ אֲשֶׁר-בּוֹ פְרִי-עֵץ, זֹרֵעַ זָרַע:  לָכֶם יִהְיֶה, לְאָכְלָה. 
<a name="30"> </a>
<b>ל</b> וּלְכָל-חַיַּת הָאָרֶץ וּלְכָל-עוֹף הַשָּׁמַיִם וּלְכֹל רוֹמֵשׂ עַל-הָאָרֶץ, אֲשֶׁר-בּוֹ נֶפֶשׁ חַיָּה, אֶת-כָּל-יֶרֶק עֵשֶׂב, לְאָכְלָה; וַיְהִי-כֵן. 
<a name="31"> </a>
<b>לא</b> וַיַּרְא אֱלֹהִים אֶת-כָּל-אֲשֶׁר עָשָׂה, וְהִנֵּה-טוֹב מְאֹד; וַיְהִי-עֶרֶב וַיְהִי-בֹקֶר, יוֹם הַשִּׁשִּׁי.  פ</p>

【讨论】:

谢谢!我从另一个将编码设置为 unicode 的源切换。 所以requests 不遵守文件本身的编码声明?这似乎很蹩脚。 @BrenBarn:有没有文件;只有 HTTP 标头。并且 Content-Type 标头中没有声明编码,所以所有requests 可以 do 都是猜测。 @MartijnPieters,我可以告诉requests 使用哪种编码吗? @Ramin:requests bug tracker 上对此进行了一些讨论。 This comment 声称提供了一种解决方法。

以上是关于使用 bs4 和请求处理后如何正确打印出 unicode 文本? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 bs4 正确解析谷歌搜索结果?

微信小程序异步处理

如何使用多处理来加速 bs4 抓取和图像下载

安装 lxml 后“bs4.FeatureNotFound:找不到具有您请求的功能的树生成器:lxml”

如何正确打印出带有“text/rtf”内容的 JTextPane 的硬拷贝?

将链接从 selenium 迭代到 bs4 并打印剥离的字符串