如何用Python Selenium从Gifer.com提取GIF对应的MP4链接?
我是网页爬虫新手,想要从gifer.com网站爬取GIF的URL。例如,搜索关键词"smile"后,获取所有列出的GIF对应的<source>元素的src属性(示例为https://i.gifer.com/ON0.mp4)。
对应的HTML结构片段:
<div class="page-media-swipe desktop"> <div class="container"> <div class="swipe-left"> <span class="icon-arrow-left-2 icon" style="color: rgb(255, 255, 255); font-size: 44px;"></span> </div> <div class="media desktop" style="width: 367.462px;"> <div style="padding-top: 122.462%;"> <div class="media-container1"> <div class="media-container2" style="width: 367.462px;"> <div> <video poster="https://i.gifer.com/fetch/w300-preview/d0/d0e6e89a42c43d31b5913e232d87af7b.gif" class="full-media" loop="" autoplay="" playsinline=""> <source src="https://i.gifer.com/ON0.mp4" type="video/mp4"> </video> </div> </div> </div> </div> </div> <div class="swipe-right"> <span class="icon-arrow-right-2 icon" style="color: rgb(255, 255, 255); font-size: 44px;"> </span> </div> </div> </div>
我尝试用Python+Selenium编写了代码,但只获取到了4个media-container2元素对象,不知道如何提取对应的src链接:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By options = Options() options.headless = True options.add_argument("--window-size=1920,1200") driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver.get("https://gifer.com/en/gifs/smile") imgResults = driver.find_elements(By.CLASS_NAME, "media-container2") print(len(imgResults)) #print(driver.page_source) for i in range(0,len(imgResults)): print(imgResults[i]) driver.quit()
代码输出:
<selenium.webdriver.remote.webelement.WebElement (session="fac424650675a90b2a8dee91efdc01f4", element="16e771ca-37d8-45a0-8200-0f03da0b7d14")>
<selenium.webdriver.remote.webelement.WebElement (session="fac424650675a90b2a8dee91efdc01f4", element="8c9abdcb-bc9d-47da-9958-109e722b3ae9")>
<selenium.webdriver.remote.webelement.WebElement (session="fac424650675a90b2a8dee91efdc01f4", element="d9640144-4ba1-414b-aa4f-5141387335ef")>
<selenium.webdriver.remote.webelement.WebElement (session="fac424650675a90b2a8dee91efdc01f4", element="9626db84-1da9-42ad-b314-56222a5e933b")>
现在需要解决的问题是如何从这些元素中提取每个video下source标签的src链接,同时能获取更多(成千上万个)结果。
1. 提取单个元素的src链接
你已经定位到了media-container2元素,接下来需要在每个该元素内部,定位到<video>标签下的<source>元素,然后获取其src属性。可以用find_element()方法在每个子元素内查找,或者直接用XPath一次性定位所有目标元素。
修改后的基础代码:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC options = Options() options.headless = True options.add_argument("--window-size=1920,1200") driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver.get("https://gifer.com/en/gifs/smile") # 等待页面加载出目标元素,避免因动态加载导致找不到元素 wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.CLASS_NAME, "media-container2"))) # 直接定位所有source元素,路径为media-container2下的video里的source sources = driver.find_elements(By.XPATH, "//div[@class='media-container2']//video/source") # 提取每个source的src属性 for source in sources: src_url = source.get_attribute("src") print(src_url) driver.quit()
2. 获取更多结果(处理动态滚动加载)
gifer.com会在滚动页面时加载更多内容,如果你需要获取成千上万个结果,需要模拟滚动操作,直到没有新内容加载为止。
添加滚动逻辑的完整代码:
from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time options = Options() options.headless = True options.add_argument("--window-size=1920,1200") # 禁用图片加载,提升爬取速度(可选) options.add_argument("--blink-settings=imagesEnabled=false") driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver.get("https://gifer.com/en/gifs/smile") wait = WebDriverWait(driver, 10) wait.until(EC.presence_of_element_located((By.CLASS_NAME, "media-container2"))) # 存储已获取的URL,避免重复 collected_urls = set() last_height = driver.execute_script("return document.body.scrollHeight") while True: # 定位当前页面所有source元素 sources = driver.find_elements(By.XPATH, "//div[@class='media-container2']//video/source") for source in sources: src_url = source.get_attribute("src") if src_url: collected_urls.add(src_url) # 滚动到页面底部 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(2) # 等待新内容加载 # 检查页面高度是否变化,判断是否还有新内容 new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height # 输出所有收集到的URL print(f"共收集到{len(collected_urls)}个GIF链接:") for url in collected_urls: print(url) driver.quit()
关键说明
- 使用
WebDriverWait等待元素加载,避免因页面动态渲染导致的元素未找到问题。 - 通过XPath直接定位目标
<source>元素,简化层级查找。 - 模拟滚动页面并检查高度变化,实现动态加载内容的爬取。
- 使用集合存储URL,自动去重,避免重复收集同一链接。
内容的提问来源于stack exchange,提问作者PPandey

