3

我目前正在通过 python 挑战,我已经达到 4 级,看这里我只学习 python 几个月,我正在尝试学习 python 3 over 2.x 到目前为止这么好,除了当我使用这段代码时,这里是 python 2.x 版本:

import urllib, re
prefix = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="
findnothing = re.compile(r"nothing is (\d+)").search
nothing = '12345'
while True:
    text = urllib.urlopen(prefix + nothing).read()
    print text
    match = findnothing(text)
    if match:
        nothing = match.group(1)
        print "   going to", nothing
    else:
        break

因此,要将其转换为 3,我将更改为:

import urllib.request, urllib.parse, urllib.error, re
prefix = "http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing="
findnothing = re.compile(r"nothing is (\d+)").search
nothing = '12345'
while True:
    text = urllib.request.urlopen(prefix + nothing).read()
    print(text)
    match = findnothing(text)
    if match:
        nothing = match.group(1)
        print("   going to", nothing)
    else:
        break

因此,如果我运行 2.x 版本,它工作正常,通过循环,抓取 url 并走到最后,我得到以下输出:

and the next nothing is 72198
   going to 72198
and the next nothing is 80992
   going to 80992
and the next nothing is 8880
   going to 8880 etc

如果我运行 3.x 版本,我会得到以下输出:

b'and the next nothing is 44827'
Traceback (most recent call last):
  File "C:\Python32\lvl4.py", line 26, in <module>
    match = findnothing(b"text")
TypeError: can't use a string pattern on a bytes-like object

因此,如果我在这一行中将 r 更改为 ab

findnothing = re.compile(b"nothing is (\d+)").search

我得到:

b'and the next nothing is 44827'
   going to b'44827'
Traceback (most recent call last):
  File "C:\Python32\lvl4.py", line 24, in <module>
    text = urllib.request.urlopen(prefix + nothing).read()
TypeError: Can't convert 'bytes' object to str implicitly

有任何想法吗?

我对编程很陌生,所以请不要咬我的头。

_bk201

4

3 回答 3

4

您不能隐式混合 bytes 和 str 对象。

最简单的事情是解码返回的字节urlopen().read()并在任何地方使用 str 对象:

text = urllib.request.urlopen(prefix + nothing).read().decode() #note: utf-8

Content-Type该页面未通过标题或<meta>元素指定首选字符编码。我不知道默认编码应该是什么,text/htmlrfc 2068 说

当发送者没有提供明确的字符集参数时,“文本”类型的媒体子类型被定义为在通过 HTTP 接收时具有“ISO-8859-1”的默认字符集值。

于 2012-02-26T13:03:47.343 回答
1

正则表达式仅对文本有意义,对二进制数据无效。因此,请保留findnothing = re.compile(r"nothing is (\d+)").search并转换text为字符串。

于 2012-02-26T13:04:21.247 回答
0

而不是urllib我们正在使用requests,它有两个选项(也许你可以在 urllib 中搜索类似的选项)

响应对象

import requests
>>> response = requests.get('https://api.github.com')

使用response.content- 具有bytes类型

>>> response.content
b'{"current_user_url":"https://api.github.com/user","current_us...."}'

使用时response.text- 您有编码的响应

>>> response.text
'{"current_user_url":"https://api.github.com/user","current_us...."}'

默认编码是utf-8,但您可以像这样在请求之后立即设置它

import requests
>>> response = requests.get('https://api.github.com')
>>> response.encoding = 'SOME_ENCODING'

然后response.text将内容保存在您请求的编码中...

于 2019-11-04T12:34:57.070 回答