使用BeautifulSoup获取雅虎财经链接及解决滚动加载问题
Yahoo财经新闻链接爬取问题解决方案
一、链接格式异常的原因与修复
原因分析
你拿到的异常链接其实是相对路径,而正常的完整链接是绝对路径。Yahoo财经页面里部分文章的<a>标签没有写全域名,只保留了域名之后的路径部分,所以直接提取href属性就会得到这种不完整的链接,没法直接访问。
修复方法
我们可以用Python自带的urllib.parse.urljoin工具,把相对路径和网站基础域名拼接成完整的绝对URL。修改后的代码如下:
import requests from bs4 import BeautifulSoup from urllib.parse import urljoin url = "https://finance.yahoo.com/topic/stock-market-news" base_url = "https://finance.yahoo.com" r1 = requests.get(url) page = r1.content soup = BeautifulSoup(page, 'html5lib') href = soup.find_all('a') boxes = [] links = [] for ref in href: curr = ref.parent.find('u') if curr is not None: boxes.append(ref) # 用urljoin拼接相对路径和基础域名,生成完整可访问的链接 full_link = urljoin(base_url, ref['href']) links.append(full_link) print(boxes) print(links)
处理后,像/news/stock-market-news-live-july-30-2020-221505732.html这类相对路径,会自动转成https://finance.yahoo.com/news/stock-market-news-live-july-30-2020-221505732.html这种可直接访问的完整链接。
二、实现滚动加载指定数量的文章链接
Yahoo财经的滚动加载是动态触发内容加载,直接用requests只能拿到初始页面的内容,无法获取滚动后加载的新内容。这里推荐用selenium模拟浏览器操作,它能直观模拟用户滚动页面的行为,直到获取到你需要的10条(或更多)链接。
步骤与代码
- 先安装selenium:
pip install selenium - 下载对应浏览器的驱动(比如Chrome的chromedriver,要和你的浏览器版本匹配)
- 运行以下代码模拟滚动并收集链接:
from selenium import webdriver from selenium.webdriver.common.by import By from urllib.parse import urljoin import time url = "https://finance.yahoo.com/topic/stock-market-news" base_url = "https://finance.yahoo.com" target_count = 10 # 你想要获取的链接数量 driver = webdriver.Chrome() # 若用其他浏览器,换成对应的驱动,比如Firefox() driver.get(url) links = set() # 用集合存储,避免重复抓取同一链接 while len(links) < target_count: # 提取当前页面符合条件的链接 current_links = driver.find_elements(By.TAG_NAME, 'a') for ref in current_links: parent = ref.find_element(By.XPATH, '..') try: # 检查父元素是否包含<u>标签,匹配你之前的筛选逻辑 parent.find_element(By.TAG_NAME, 'u') full_link = urljoin(base_url, ref.get_attribute('href')) links.add(full_link) except: continue # 滚动到页面底部,触发新内容加载 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(2) # 等待页面加载,网络慢可适当延长时间 # 转成列表并取前target_count个链接 final_links = list(links)[:target_count] print(final_links) driver.quit()
额外说明
- 用
set存储链接是为了避免重复,因为滚动加载时可能会重复出现之前的内容 - 如果不想用selenium,也可以通过抓包找到Yahoo加载更多内容的API接口,直接请求API获取数据,这种方式效率更高,但需要分析页面的网络请求,相对复杂一些。
内容的提问来源于stack exchange,提问作者shaked migdal
相关产品推荐
相关产品推荐

