使用BeautifulSoup无法爬取谷歌新冠地图表格全部行的求助
解决Google新冠地图表格动态加载数据爬取问题
我尝试从网站https://google.com/covid19-map/?hl=en爬取表格行以获取新冠病毒传播数据,但仅返回15行,无法获取全部行。该表格在网页中未完全显示,需滚动才能查看完整内容,恳请提供技术帮助。
代码如下:
import requests from bs4 import BeautifulSoup URL = "https://google.com/covid19-map/?hl=en" r = requests.get(URL) soup = BeautifulSoup(r.content, 'html5lib') all_rows = soup.findAll('tr', attrs = {'class':'A5V3jc'}) for i in range(len(all_rows)): # Getting image link img_link = all_rows[i].find('img') if img_link != None: print(img_link['src']) # Getting name field name = all_rows[i].find('span') if(name != None): print(name.text, end =" ") # getting remaining data remaining_entries = all_rows[i].findAll('td', attrs = {'class':'uMsnNd HAChlc'}) for j in remaining_entries: if(j != None): print(j.text, end=" ") print("\n\n")
问题核心原因
你用requests + BeautifulSoup的方案只能拿到15行数据,是因为这个页面采用了动态加载机制:初始页面只会渲染浏览器可见区域的15行表格内容,剩下的行需要你滚动页面时,触发后端的AJAX请求来加载并渲染。而requests只能抓取页面的初始静态HTML,无法模拟滚动操作,自然拿不到后续加载的内容。
可行解决方案:用Selenium模拟浏览器交互
要获取全部表格行,我们需要用Selenium来模拟真实用户的浏览器操作——它能打开页面、滚动到底部触发加载,等所有内容渲染完成后再提取数据。
1. 准备工作
首先安装Selenium库,以及对应你浏览器的驱动(以Chrome为例):
pip install selenium
然后下载与你本地Chrome版本匹配的驱动(注意版本必须对应),可以放到系统PATH目录,或者和你的Python脚本放在同一文件夹下。
2. 优化后的完整代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from bs4 import BeautifulSoup import time URL = "https://google.com/covid19-map/?hl=en" # 初始化Chrome浏览器(如果用Firefox/Edge,替换成对应driver即可) driver = webdriver.Chrome() driver.get(URL) # 等待页面初始表格加载完成,避免过早解析 wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.CLASS_NAME, "A5V3jc"))) # 循环滚动页面,直到所有内容加载完成 last_scroll_height = driver.execute_script("return document.body.scrollHeight") while True: # 执行JavaScript滚动到页面底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待2秒让新内容加载(可根据网络速度调整) time.sleep(2) # 获取新的页面高度 new_scroll_height = driver.execute_script("return document.body.scrollHeight") # 如果高度不再变化,说明所有内容已加载 if new_scroll_height == last_scroll_height: break last_scroll_height = new_scroll_height # 获取完整渲染后的页面源码 page_source = driver.page_source # 关闭浏览器 driver.quit() # 用BeautifulSoup解析页面 soup = BeautifulSoup(page_source, 'html5lib') all_rows = soup.findAll('tr', attrs={'class':'A5V3jc'}) # 遍历提取数据(保留你原来的逻辑,优化了变量名) for row in all_rows: # 获取国旗图片链接 img_link = row.find('img') if img_link: print(img_link['src']) # 获取地区名称 name = row.find('span') if name: print(name.text, end="\t") # 获取其余数据列 remaining_entries = row.findAll('td', attrs={'class':'uMsnNd HAChlc'}) for entry in remaining_entries: if entry: print(entry.text, end="\t\t") print("\n\n")
代码关键说明
- 等待机制:用
WebDriverWait确保初始表格加载完成后再开始操作,避免出现找不到元素的错误。 - 滚动加载逻辑:通过执行JavaScript滚动页面,每次滚动后等待内容加载,直到页面高度不再变化——这是判断所有内容加载完成的关键。
- 解析完整页面:拿到浏览器渲染后的完整HTML,再用BeautifulSoup解析,就能获取全部表格行了。
额外注意事项
- 浏览器驱动版本必须和本地浏览器版本一致,否则会出现启动失败的问题。
- 如果网络较慢,可以适当延长
time.sleep(2)的时间,确保新内容有足够时间加载。 - 如果你不想让浏览器窗口显示,可以使用无头模式(添加
options.add_argument('--headless=new')到ChromeOptions里)。
内容的提问来源于stack exchange,提问作者Tanishq Vyas
相关产品推荐
相关产品推荐

