【问题标题】:BeautifulSoup returning none when element definitely exists当元素确实存在时,BeautifulSoup 不返回任何内容
【发布时间】:2018-04-16 11:00:38
【问题描述】:

我是网络抓取的新手,一直在使用 BeautifulSoup 来抓取每日抵押贷款利率。但是,我试图抓取的许多服务站点都返回“无”或空列表。我试图抓取的标签肯定存在,我只是不明白为什么会这样。下面是一个例子。

html=urlopen('https://www.popular.com/en/mortgages/')
bs0bj=BeautifulSoup(html, 'html.parser');
rate=bs0bj.find('span', {'class':'text-md text-popular-medium-blue'}).div
print(rate)

【问题讨论】:

  • 我认为您不需要 .div 部分。
  • @jordiburgos 不是重复的,这里的问题不同。

标签: python html beautifulsoup nonetype


【解决方案1】:

使用 pip install html5lib 但我认为使用“pip install bs4(beautifulSoup)一切都应该自动安装如果你像我一样使用PyCharm,在命令行中的“pip install bs4”之后,打开Pycharm并转到解释器设置,添加beautifulsooup 和html5lib html5lib 就像解析器它和HTML.parser 一样。两者都是解析器更多信息这里是beautifulsoup 文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser

【讨论】:

    【解决方案2】:

    要获得你想要的数据,你可以将 selenium 与 python 结合使用,如下所示:

    from bs4 import BeautifulSoup
    from selenium  import webdriver
    
    driver = webdriver.Chrome()
    driver.get('https://www.popular.com/en/mortgages/')
    
    soup = BeautifulSoup(driver.page_source,"lxml")
    item = soup.select('.table-responsive')[0].select("span div")[0].text
    print(item)
    driver.quit()
    

    结果:

    2.75%
    

    【讨论】:

      【解决方案3】:

      正如 rubik 所说,费率是使用 JS 动态加载的。好在内容的结构比较简单,我是这样分析的:

      在 Chrome(或其他浏览器)中打开一个新标签页并右键单击,然后选择 view-source。切换到Network 选项卡并检查preserve log 选项。

      现在,打开网站https://www.popular.com/en/mortgages/。加载的内容可以在左侧面板中看到。

      检查每个项目并分析其Preview 内容,直到找到要废弃的项目。这是我发现的,2.75% 与网站上显示的抵押贷款利率值匹配。

      现在,切换到Headers 选项卡并检查Request URL,这是发送到服务器的最终请求。

      接下来就是分析Request URL https://apps.popular.com/navs/rates_wm_modx.php?id_rates=1&textcolor=3784D2&backgroundcolor=ffffff&t=1

      我猜textcolorbackgroundcolor表示css信息,所以删除了,发现url还是有效的。

      现在我们有了一个更简单的网址:https://apps.popular.com/navs/rates_wm_modx.php?id_rates=1&t=1

      很明显,id_rates 表示抵押贷款利率的顺序,没有任何分析。问题是:t 是什么意思?

      这可以通过分析其他预览内容找到规则来解决。这里我想跳过这个过程,直接给出结论。

      t=1表示Annual interestt=2表示APRt=6表示P&I Payment等:

      完成这些之后,现在您可以直接从请求 URL 中抓取内容:

      from urllib2 import urlopen
      import  re
      
      file=urlopen('https://apps.popular.com/navs/rates_wm_modx.php?id_rates=1&t=1')
      annual_interest = re.findall(r"\d+\.\d+", str(file.read()))[0]
      #the annual interest is 2.75
      

      【讨论】:

        【解决方案4】:

        如果您检查页面源(例如通过 Chrome 或 Firefox 中的 view-source:,或将您的 html 字符串写入文件),您会发现您要查找的元素不存在。事实上,费率是动态加载的:

        <td>
          <span class="text-md text-popular-medium-blue">
            <script type="text/javascript" src = "https://apps.popular.com/navs/rates_wm_modx.php?id_rates=1&textcolor=3784D2&backgroundcolor=ffffff&t=1"></script>
          </span>
        </td>
        

        您可以跟踪脚本 URL,您会看到响应类似于以下内容:

        document.write('<div>2.75%</div>')
        

        此响应可能足够有规律,可以对其使用正则表达式。

        【讨论】:

        • @SuperStew 是的,因为我们正在读取 Javascript 源代码,而不是执行它。这里的替代方法是使用无头浏览器或像 Splash 这样的代理来渲染所有内容,然后 OP 中的代码就可以工作了。但对于这个简单的案例,这绝对是矫枉过正。
        猜你喜欢
        • 2022-11-28
        • 1970-01-01
        • 2018-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-15
        相关资源
        最近更新 更多