从谷歌搜索页面抓取片段文本

时间:2021-04-27 07:01:19

标签: python html selenium web-scraping google-search

当我们在 google 中搜索问题时,它通常会在如下片段中生成答案:

result for when+barak+obama+born

我的目标是在我的 python 代码中抓取这段文本(“August 4, 1961”在屏幕截图中用红色标记圈起来)。

在尝试抓取文本之前,我使用以下代码将 Web 响应存储在文本文件中:

page = requests.get("https://www.google.com/search?q=when+barak+obama+born")
soup = BeautifulSoup(page.content, 'html.parser')
out_file = open("web_response.txt", "w", encoding='utf-8')
out_file.write(soup.prettify())

inspect element 部分,我注意到代码片段在 div class Z0LcW XcVN5d 内(在屏幕截图中用绿色标记圈起来)。但是,我的 txt 文件中的响应不包含此类文本,更不用说类名了。

我还尝试过 this solution,作者在其中抓取了 ID 为 rhs_block 的项目。但是我的回复没有这样的id。

我在我的响应 txt 文件中搜索了“1961 年 8 月 4 日”的出现,并试图理解它是否可能是片段。但似乎没有一个是我正在寻找的。

我的计划是获取代码段的 div id 或类名并找到它的内容,如下所示:

# IT'S A PSEUDO CODE
containers = soup.find_all(class or id = 'somehting')
for tag in containers:
    print(f"tag text : {tag.text}")

有没有办法做到这一点?

注意:我也可以使用 beautifulsoup 和 requests 以外的库,只要它可以产生结果。

2 个答案:

答案 0 :(得分:1)

Selenium 会产生你需要的结果。 这很方便,因为您可以添加任何等待并查看屏幕上实际发生的情况。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


driver = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')

driver.get('https://google.com/')
assert "Google" in driver.title
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".gLFyf.gsfi")))
input_field = driver.find_element_by_css_selector(".gLFyf.gsfi")
input_field.send_keys("how many people in the world")
input_field.send_keys(Keys.RETURN)

wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".Z0LcW.XcVN5d")))
result = driver.find_element_by_css_selector(".Z0LcW.XcVN5d").text
print(result)
driver.close()
driver.quit()

结果可能会让你感到惊讶:)

您需要安装 SeleniumChromedriver。对于 Windows,您需要将 Chromedriver 可执行文件放在路径中,或者在 Linux 中显示它的路径。我的示例适用于 Linux。

答案 1 :(得分:1)

无需使用 Error: java.io.IOException: Type mismatch in key from map: expected org.apache.hadoop.io.IntWritable, received org.apache.hadoop.io.Text at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1079) at org.apache.hadoop.mapred.MapTask$NewOutputCollector.write(MapTask.java:721) at org.apache.hadoop.mapreduce.task.TaskInputOutputContextImpl.write(TaskInputOutputContextImpl.java:89) at org.apache.hadoop.mapreduce.lib.map.WrappedMapper$Context.write(WrappedMapper.java:112) at Lab7$JobMapper.map(Lab7.java:53) at Lab7$JobMapper.map(Lab7.java:39) at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:146) at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:793) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341) at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:177) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/javax.security.auth.Subject.doAs(Subject.java:423) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1886) at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:171) ,您可以使用 Seleniumrequests 来实现这一点,因为您需要的一切都位于 HTML 中,并且没有动态 JavaScript。

online IDE 中的代码和示例:

BS4

输出:

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"
}

html = requests.get('https://www.google.com/search?q=Barack Obama born date', headers=headers).text

soup = BeautifulSoup(html, 'lxml')

born = soup.select_one('.XcVN5d').text
age = soup.select_one('.kZ91ed').text

print(born)
print(age)
相关问题