【问题标题】:soup class selector returns an empty list汤类选择器返回一个空列表
【发布时间】:2019-11-29 01:53:37
【问题描述】:

我正在尝试从谷歌搜索页面检索链接列表,但漂亮的汤选择器返回一个空列表。

我使用requests获取页面代码并使用bs4 BeautifulSoup解析检索到的响应,然后使用soup.select方法获取某个类。我最终得到一个空列表

import webbrowser as wbb
import requests
from bs4 import BeautifulSoup as BS

term = "minmax"
res = requests.get('https://www.google.com/search?q={}'.format(term))
soup = BS(res.text)
links= soup.select(".rc")

我希望列表 links 包含 rc 类,但得到一个空列表

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    您需要使用user-agent 标头。 Google 似乎会拒绝没有请求的请求。

    这行得通:

    import requests
    from bs4 import BeautifulSoup
    
    term = "minmax"
    res = requests.get('https://www.google.com/search?q={}'.format(term), 
                       headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'})
    res.raise_for_status()
    soup = BeautifulSoup(res.text, 'html.parser')
    links = soup.select(".rc")
    print(links)
    

    【讨论】:

    • OP 使用与您完全相同的选择器。诀窍是指定用户代理。请相应地更新您的答案。
    【解决方案2】:

    这是因为请求获取的 HTML 中没有带有 class="rc" 的标签。可以添加如下代码sn-ps来确认HTML源来确认。

    with open("google.html", "w") as fout:
        fout.write(soup.prettify())
    

    这将创建 google.html。用任何文本编辑器打开它,你不会找到任何带有 class="rc" 的标签。您可能会在 Google Chrome 的 DevTools 或其他浏览器的等效工具中找到带有 class="rc" 的标签。

    为什么在 DevTools 中查看 HTML 时有标签带有 class="rc" 并且 HTML 请求获取中没有标签?这是因为请求获取的 HTML 是 Google Http 服务器响应的 原始 HTML,您在 DevTools 中查看的 HTML JavaScript DOM 修改 HTML 之后显示 HTML。 p>

    因为通过请求获取 HTML 时没有 JavaScript 会自动执行,所以你必须根据原始 HTML(JavaScript DOM 修改 HTML 之前的 HTML)构建 CSS 选择器。如果您不想每次都编写 python 代码来获取原始 HTML,您也可以在 Google Chrome 中查看原始 HTML。只需查看您想要的网页,然后右键单击并选择“查看页面源”。它将显示 JavaScript DOM 更改 HTML 内容之前的原始 HTML。

    似乎链接以以下代码开头。

    <a href="/url?q=
    

    所以你可以像这样改变 CSS 选择器。

    links= soup.select('a[href^="/url?q="]')
    

    【讨论】:

      【解决方案3】:

      这是因为没有指定 user-agent,因此 Google 阻止了请求,并且您收到了具有不同选择器的完全不同的 HTML,因为默认请求 user-agentpython-requests,Google 理解它并阻止了请求。详细了解request headers

      user-agent 传递给request headers

      headers = {
          'User-agent':
          "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"
      }
      
      requests.get("YOUR_URL", headers=headers)
      

      您可以使用f-string 代替.format()

      term = "minmax"
      res = requests.get(f'https://www.google.com/search?q={term}')
      

      代码和full example in the online IDE

      from bs4 import BeautifulSoup
      import requests, json, lxml
      
      headers = {
          'User-agent':
          "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"
      }
      
      params = {
        "q": "fus ro dah"
      }
      
      html = requests.get('https://www.google.com/search', headers=headers, params=params)
      soup = BeautifulSoup(html.text, 'lxml')
      
      for result in soup.select('.tF2Cxc'):
        title = result.select_one('.DKV0Md').text
        link = result.select_one('.yuRUbf a')['href']
        print(f"{title}\n{link}\n")
      
      ------
      '''
      Unrelenting Force (Skyrim) | Elder Scrolls | Fandom
      https://elderscrolls.fandom.com/wiki/Unrelenting_Force_(Skyrim)
      
      Fus Ro Dah | Know Your Meme
      https://knowyourmeme.com/memes/fus-ro-dah
      
      Skyrim:Unrelenting Force - The Unofficial Elder Scrolls Pages
      https://en.uesp.net/wiki/Skyrim:Unrelenting_Force
      
      Fus ro dah - Urban Dictionary
      https://www.urbandictionary.com/define.php?term=Fus%20ro%20dah
      
      Fus Ro Dah GIFs | Tenor
      https://tenor.com/search/fus-ro-dah-gifs
      
      Fus Ro Dah | Etsy
      https://www.etsy.com/market/fus_ro_dah
      
      Super Fus Ro Dah - Skyrim Special Edition - Nexus Mods
      https://www.nexusmods.com/skyrimspecialedition/mods/4889/
      '''
      

      或者,您可以使用来自 SerpApi 的 Google Results API 来做同样的事情。这是一个带有免费计划的付费 API。

      您的情况的不同之处在于,您不必弄清楚为什么CSS 选择器不起作用,或者您收到了完全不同的 HTML 结果,因为搜索引擎的提取和绕过块已经完成 -用户。唯一真正需要做的就是遍历 JSON 字符串并得到你需要的。

      import os
      from serpapi import GoogleSearch
      
      params = {
          "engine": "google",
          "q": "fus ro dah",
          "hl": "en",
          "api_key": os.getenv("API_KEY"),
      }
      
      search = GoogleSearch(params)
      results = search.get_dict()
      
      for result in results["organic_results"]:
        print(f"{result['title']}\n{result['link']}\n")
      
      --------
      '''
      Unrelenting Force (Skyrim) | Elder Scrolls | Fandom
      https://elderscrolls.fandom.com/wiki/Unrelenting_Force_(Skyrim)
      
      Fus Ro Dah | Know Your Meme
      https://knowyourmeme.com/memes/fus-ro-dah
      
      Skyrim:Unrelenting Force - The Unofficial Elder Scrolls Pages
      https://en.uesp.net/wiki/Skyrim:Unrelenting_Force
      
      Fus ro dah - Urban Dictionary
      https://www.urbandictionary.com/define.php?term=Fus%20ro%20dah
      
      Fus Ro Dah GIFs | Tenor
      https://tenor.com/search/fus-ro-dah-gifs
      
      Fus Ro Dah | Etsy
      https://www.etsy.com/market/fus_ro_dah
      
      Super Fus Ro Dah - Skyrim Special Edition - Nexus Mods
      https://www.nexusmods.com/skyrimspecialedition/mods/4889/
      '''
      

      免责声明,我为 SerpApi 工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-09
        • 1970-01-01
        • 2018-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多