代码之家  ›  专栏  ›  技术社区  ›  user3885774

将web数据传递到Beautiful Soup-空列表

  •  7
  • user3885774  · 技术社区  · 10 年前

    我重新检查了我的代码,并查看了打开URL以将web数据传递到Beautiful Soup中的类似操作,出于某种原因,我的代码只是没有返回任何内容,尽管格式正确:

    >>> from bs4 import BeautifulSoup
    
    >>> from urllib3 import poolmanager
    
    >>> connectBuilder = poolmanager.PoolManager()
    
    >>> content = connectBuilder.urlopen('GET', 'http://www.crummy.com/software/BeautifulSoup/')
    
    >>> content
    <urllib3.response.HTTPResponse object at 0x00000000032EC390>
    
    >>> soup = BeautifulSoup(content)
    
    >>> soup.title
    >>> soup.title.name
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'name'
    >>> soup.p
    >>> soup.get_text()
    ''
    
    >>> content.data
    a stream of data follows...
    

    如图所示,很明显,urlopen()返回一个HTTP响应,该响应由变量内容捕获,它可以读取响应的状态,但在传递到Beautiful Soup之后,web数据不会转换为Beautiful汤对象(变量汤)。您可以看到,我尝试读取了一些标记和文本,get_text()返回一个空列表,这很奇怪。

    奇怪的是,当我通过content.data访问web数据时,数据会显示出来,但由于我无法使用Beautiful Soup来解析它,所以没有用。我的问题是什么?谢谢

    4 回复  |  直到 10 年前
        1
  •  16
  •   Padraic Cunningham    10 年前

    如果你只是想抓取页面, requests 将获得您需要的内容:

    from bs4 import BeautifulSoup
    
    import requests
    r = requests.get('http://www.crummy.com/software/BeautifulSoup/')
    soup = BeautifulSoup(r.content)
    
    In [59]: soup.title
    Out[59]: <title>Beautiful Soup: We called him Tortoise because he taught us.</title>
    
    In [60]: soup.title.name
    Out[60]: 'title'
    
        2
  •  12
  •   shazow    10 年前

    urllib3返回一个Response对象,该对象包含 .data 其具有预加载的车身有效载荷。

    按顶级快速启动 usage example here ,我会这样做:

    import urllib3
    http = urllib3.PoolManager()
    response = http.request('GET', 'http://www.crummy.com/software/BeautifulSoup/')
    
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(response.data)  # Note the use of the .data property
    ...
    

    其余部分应按预期工作。

    --

    关于原始代码中的错误:

    你通过了整个 response 对象而不是主体有效载荷。这通常应该很好,因为 回答 对象是类似文件的对象, 除了 在本例中,urllib3已经使用了所有的响应并为您解析它,这样就没有什么可以做的了 .read() 。这就像传递已读取的文件指针。 数据 另一方面将访问已经读取的数据。

    如果您想将urllib3响应对象用作类似文件的对象,则需要禁用内容预加载,如下所示:

    response = http.request('GET', 'http://www.crummy.com/software/BeautifulSoup/', preload_content=False)
    soup = BeautifulSoup(response)  # We can pass the original `response` object now.
    

    现在它应该如你所期望的那样工作。

    我知道这不是很明显的行为,作为urllib3的作者,我很抱歉我们计划 preload_content=False 默认值。也许不久的某一天( I opened an issue here ).

    --

    关于 .urlopen .request :

    .urlopen 假设您将负责对传递给请求的任何参数进行编码。在这种情况下,可以使用 .urlopen 因为您没有向请求传递任何参数,而是在一般情况下 要求 将为您做所有额外的工作,这样更方便。

    如果有人愿意为此改进我们的文档,我们将不胜感激。:)请将请购单发送至 https://github.com/shazow/urllib3 并将自己添加为贡献者!

        3
  •  2
  •   abarnert    10 年前

    如图所示,urlopen()返回一个HTTP响应,该响应由变量content捕获

    你打过的电话 content 不是内容,而是可以从中读取内容的类似文件的对象。BeautifulSoup非常乐意接受这样的东西,但打印出来用于调试并没有太大帮助。因此,让我们实际读取其中的内容,使其更易于调试:

    >>> response = connectBuilder.urlopen('GET', 'http://www.crummy.com/software/BeautifulSoup/')
    >>> response
    <urllib3.response.HTTPResponse object at 0x00000000032EC390>
    >>> content = response.read()
    >>> content
    b''
    

    这应该很清楚 BeautifulSoup 这不是问题所在。但继续:

    但是在传递到Beautiful Soup之后,web数据不会被转换为Beautiful汤对象(变量汤)。

    是的。事实上 soup.title 给了你 None 而不是提出 AttributeError 是很好的证据,但你可以直接测试它:

    >>> type(soup)
    bs4.BeautifulSoup
    

    这绝对是一个 美味浓汤 对象

    当你通过时 美味浓汤 一个空字符串,您得到的确切结果将取决于它在后台使用的解析器;如果它依赖于Python3.x stdlib,那么您将得到一个 html 节点为空 head ,和空 body ,其他都没有。所以,当你寻找 title 节点,没有节点 没有一个 .


    那么,你怎么解决这个问题?

    the documentation 说,您正在使用“最低级别的调用来提出请求,因此您需要指定所有原始详细信息。”这些原始详细信息是什么?老实说,如果你还不知道,你不应该使用这种方法教你如何处理 urllib3 在你知道基础知识不会为你提供服务之前。

    事实上,你真的不需要 URL库3 在这里。只需使用Python附带的模块:

    >>> # on Python 2.x, instead do: from urllib2 import urlopen 
    >>> from urllib.request import urlopen
    >>> r = urlopen('http://www.crummy.com/software/BeautifulSoup/')
    >>> soup = BeautifulSoup(r)
    >>> soup.title.text
    'Beautiful Soup: We called him Tortoise because he taught us.'
    
        4
  •  0
  •   Community Nick Dandoulakis    7 年前

    我漂亮的汤代码在一个环境(我的本地机器)中工作,并在另一个环境中返回一个空列表(ubuntu14服务器)。

    我已经解决了更改安装的问题。 其他线程中的详细信息:

    Html parsing with Beautiful Soup returns empty list