使用Python BeautifulSoup提取a标签href仅返回..符号问题求解
问题原因与解决方案
问题原因
- 目标网站的链接是JavaScript动态渲染生成的:静态HTML返回时,a标签的href属性默认填充的是
..,完整URL是页面加载完成后由JS动态写入到属性中的,requests只能获取未执行JS的原始静态源码,因此只能拿到..。 - 反爬校验拦截:你发起的请求未携带浏览器标识等必要头信息,网站返回了阉割版的页面内容,对应a标签的href属性被替换为
..。
解决方案
方案1:补全请求头校验静态内容,拼接相对路径
先补全请求头模拟浏览器访问,确认返回的静态源码内容,如果是相对路径规则可以直接拼接域名得到完整链接:
import requests from bs4 import BeautifulSoup # 模拟浏览器的请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Referer": "http://www.saij.gob.ar/" } links = [] for item in pages: r = requests.get(item, headers=headers) soup = BeautifulSoup(r.text, "html.parser") a_tag = soup.find("dd", class_="tit-colapsado").find('a') raw_link = a_tag.attrs['href'] # 拼接域名得到完整链接 full_link = "http://www.saij.gob.ar/" + raw_link.lstrip('./') links.append(full_link) print(links)
方案2:使用动态渲染工具获取JS执行后的完整内容
如果确认是动态渲染导致的问题,使用selenium等工具加载页面等待JS执行完成后再提取属性:
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 # 初始化Chrome浏览器,需要提前安装Chrome和对应版本的ChromeDriver driver = webdriver.Chrome() links = [] for item in pages: driver.get(item) # 等待目标a标签加载完成 a_tag = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "dd.tit-colapsado a")) ) # 获取渲染完成后的完整href属性 full_link = a_tag.get_attribute('href') links.append(full_link) print(links) driver.quit()
方案3:抓包获取数据接口
更高效率的方式是打开浏览器开发者工具的「网络」面板,筛选XHR/ fetch请求,找到网站加载链接数据的后端接口,直接请求接口获取完整URL,不需要解析HTML。
内容的提问来源于stack exchange,提问作者Faizan NAZIR
相关产品推荐
相关产品推荐

