python 从靓汤中提取href< a>

z18hc3ub  于 2023-02-02  发布在  Python
关注(0)|答案(2)|浏览(121)

我试图从谷歌搜索结果中提取一个链接,Inspect元素告诉我我感兴趣的部分有“class = r”,第一个结果如下所示:

<h3 class="r" original_target="https://en.wikipedia.org/wiki/chocolate" style="display: inline-block;">
    <a href="https://en.wikipedia.org/wiki/Chocolate" 
       ping="/url?sa=t&amp;source=web&amp;rct=j&amp;url=https://en.wikipedia.org/wiki/Chocolate&amp;ved=0ahUKEwjW6tTC8LXZAhXDjpQKHSXSClIQFgheMAM" 
       saprocessedanchor="true">
        Chocolate - Wikipedia
    </a>
</h3>

要提取“href”I do:

import bs4, requests
res = requests.get('https://www.google.com/search?q=chocolate')
googleSoup = bs4.BeautifulSoup(res.text, "html.parser")
elements= googleSoup.select(".r a")
elements[0].get("href")

但我意外地得到:

'/url?q=https://en.wikipedia.org/wiki/Chocolate&sa=U&ved=0ahUKEwjHjrmc_7XZAhUME5QKHSOCAW8QFggWMAA&usg=AOvVaw03f1l4EU9fYd'

我想去的地方:
"https://en.wikipedia.org/wiki/Chocolate"
“ping”这个属性似乎把它搞混了。有什么想法吗?

tpxzln5u

tpxzln5u1#

发生了什么?

如果你打印响应内容(例如googleSoup.text),你会看到你得到的是一个完全不同的HTML。页面源和响应内容不匹配。
这是发生的,因为内容是动态加载的;即使这样,页面源代码和响应内容也是相同的。2(但是在检查元素时看到的HTML是不同的。3)
对此的基本解释是Google识别Python脚本并更改其响应。

溶液:

您可以传递一个 * fake * User-Agent,使脚本看起来像一个真正的浏览器请求。

代码:

headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'}

r = requests.get('https://www.google.co.in/search?q=chocolate', headers=headers)
soup = BeautifulSoup(r.text, 'lxml')

elements = soup.select('.r a')
print(elements[0]['href'])
    • 输出**:
https://en.wikipedia.org/wiki/Chocolate

资源:

cbjzeqam

cbjzeqam2#

正如另一个答案所提到的,这是因为没有指定user-agent。默认的requestsuser-agent是python-requests,因此Google阻止请求,因为它知道这是一个bot,而不是一个"真正的"用户访问。
User-agent通过将此信息添加到HTTP request headers来伪造用户访问。这可以通过传递自定义头(check what's yours user-agent)来完成:

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)

此外,要获得更准确的结果,您可以传递URL参数:

params = {
  "q": "samurai cop, what does katana mean",  # query
  "gl": "in",                                 # country to search from
  "hl": "en"                                  # language
  # other parameters 
}
requests.get("YOUR_URL", params=params)

在线IDE中的代码和完整示例(* 由于CSS选择器更改,其他答案中的代码将引发错误 *):

from bs4 import BeautifulSoup
import requests, 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": "samurai cop what does katana mean",
  "gl": "in",
  "hl": "en"
}

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')

-------
'''
Samurai Cop - He speaks fluent Japanese - YouTube
https://www.youtube.com/watch?v=paTW3wOyIYw

Samurai Cop - What does "katana" mean? - Quotes.net
https://www.quotes.net/mquote/1060647

Samurai Cop (1991) - Mathew Karedas as Joe Marshall - IMDb
https://www.imdb.com/title/tt0130236/characters/nm0360481

...
'''

或者,您可以使用SerpApi的Google Organic Results API来实现同样的功能,这是一个免费的付费API。
在您的情况下,不同之处在于您只需要迭代结构化JSON并快速获得所需数据,而不是找出某些东西不能正常工作的原因,然后随着时间的推移维护解析器。
要集成的代码:

import os
from serpapi import GoogleSearch

params = {
    "engine": "google",
    "q": "samurai cop what does katana mean",
    "hl": "en",
    "gl": "in",
    "api_key": os.getenv("API_KEY"),
}

search = GoogleSearch(params)
results = search.get_dict()

for result in results["organic_results"]:
  print(result['title'])
  print(result['link'])
  print()

------
'''
Samurai Cop - He speaks fluent Japanese - YouTube
https://www.youtube.com/watch?v=paTW3wOyIYw

Samurai Cop - What does "katana" mean? - Quotes.net
https://www.quotes.net/mquote/1060647
...
'''

免责声明我为SerpApi工作。

相关问题