在 python 中使用 lxml 进行网络抓取后,我得到奇怪的字符而不是土耳其字符

I get strange characters instead of turkish characters after web scraping using lxml in python

提问人:shuster 提问时间:9/21/2020 最后编辑:DisappointedByUnaccountableModshuster 更新时间:2/3/2021 访问量:537

问:

我一直在尝试使用 lxml lib 从某些网站获取数据。和 Python3。但是在网络抓取过程之后,我得到了一些奇怪的字符而不是土耳其字符。奇怪的字符如下所示。

  • TÃ1/4rkiye Engelliler Spor Yardım ve Eı (TESYEV) Genel MÃ1/4dÃ1/4rlÃ1/4Ä1/4
  • Tek ders sınavı hakkında duyuru
  • 2019-2020 AKADEMÄ°K YILI GÄ°DEN ÃÄ°LERÄ°MÄ°ZÄ°N YAPMASI GEREKEN Ä°Å

但它们应该像下面给出的那样。

  • Türkiye Engelliler Spor Yardım ve Eğitim Vakfı (TESYEV) Genel Müdürlüğü
  • Tek ders sınavı hakkında duyuru
  • 2019-2020 AKADEMİK YILI GİDEN ÖĞRENCİLERİMİZİN YAPMASI GEREKEN İŞLEMLER

我从不同的网站得到了每一句话。我不知道如何将它们转换为土耳其语文本。

这是我的代码。

import cssselect
import requests
from lxml import html

def parse_html(url, selector):
    page = requests.get(url)

    tree = html.fromstring(page.content)
    titles = tree.cssselect(selector)

    for title in titles:
        print(title.text_content().strip())

版本

  • 蟒蛇 = 3.7.4
  • lxml = 4.5.2
  • 请求 = 2.24.0
  • cssselect = 1.1.0
python 网页抓取 unicode html 解析 lxml

评论

0赞 Grzegorz Oledzki 9/21/2020
它们很可能是用不同的字符编码编写的(与代码假定的要好)。
1赞 lenz 9/21/2020
也许它们只是在打印时出现乱码。您可以使用以下函数进行验证: 。如果您看到土耳其的“T\xfcrkiye”,则文本解析正常,但在打印时损坏。如果看到“T\xc3\xbcrkiye”,则问题发生得更早(例如,某些编码标头被忽略)。ascii()print(ascii(title.text_content().strip()))
0赞 shuster 9/21/2020
当我使用该功能时,我看到“T\xc3\xbcrkiye”。所以这意味着问题发生得更早。我该如何解决?ascii()
0赞 lenz 9/21/2020
也许是cssselect的问题。我没有在这里安装它,但是如果我重复您的步骤并访问标题,它将被正确解码。(我试过 tesyev.org/tr/anasayfatree.find('.//title').text)

答:

2赞 scorix 9/21/2020 #1

import cssselect
import requests
from lxml import html

def parse_html(url, selector):
    page = requests.get(url)

    content = str(page.content, 'utf-8')

    tree = html.fromstring(content)
    titles = tree.cssselect(selector)

    for title in titles:
        print(title.text_content().strip())

为什么

unicode 字符“ı”(U+0131) 以 UTF-8 编码为0xC4B1。2 字节。

> echo -e '\u0131' | xxd -u
00000000: C4B1 0A                                  ...

page.content返回二进制响应内容

0xC4B1变为 0xC4 (U+00C4 'Ä') 和 0xB1 (U+00B1 '±')

U+00FC 'ü'(UTF-8 编码:0xC3BC)变为 0xC3 (U+00C3 'Ã') 和 0xBC (U+00BC '1/4')

评论

1赞 lenz 9/21/2020
b'C4B1'只有当您将其解释为 Latin-1 时才会成为。当我测试它时,用 UTF-8 正确解码了二进制字符串(所以我怀疑 cssselect)。'ı'lxml
0赞 shuster 9/21/2020
解决方案对我有用。感谢您的回答和评论@lenz。我想我应该详细了解 unicode 字符和 utf-8 是如何工作的。