爬虫(四)Selenium + Headless Chrome爬取Bing图片搜索结果
Bing图片搜索结果是动态加载的,如果我们直接用requests去访问页面爬取数据,那我们只能拿到很少的图片。所以我们使用Selenium + Headless Chrome来爬取搜索结果。在开始前,需要介绍一下xpath。
XPath
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。使用它让我们可以很方便地定位页面中的各种元素。详细使用方法可以看这里。
实例
from selenium import webdriver from selenium.webdriver.common.by import By import json import re import requests import os chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") driver = webdriver.Chrome(options=chrome_options) word = '深秋壁纸' url = 'https://cn.bing.com/images/search?q={}'.format(word) save_folder = 'imgs' if not os.path.exists(save_folder): os.makedirs(save_folder) driver.get(url) # 获取一行图片 rows = driver.find_elements_by_class_name("dgControl_list") t = 0 # 只点击一次“更多图片” mark = True while mark or t != len(rows): if t == len(rows): # 找到class为“mm_seemore”的div下的第一个a标签 element = driver.find_element_by_xpath("//div[@class='mm_seemore']/a[1]") # 用JS模拟点击 driver.execute_script("arguments[0].click()", element) mark = False # 翻到页面底部 driver.execute_script('window.scrollTo(0, document.body.scrollHeight)') driver.implicitly_wait(0.5) t = len(rows) rows = driver.find_elements_by_class_name("dgControl_list") print(t) img_url_list = [] for row in rows: # 找到图片所在的a标签 a_list = row.find_elements(By.XPATH, "li/div/div/a") for tag in a_list: # 获取图片链接 img_url_list.append(json.loads(tag.get_attribute('m'))['murl']) driver.quit() for i in range(len(img_url_list)): try: img = requests.get(img_url_list[i], timeout=10).content # 获取图片格式 img_format = re.search(r'\.\w+$', img_url_list[i])[0] except Exception as e: print(e) continue with open('{}/{}{}.{}'.format(save_folder, word, i, img_format[1:]), 'wb') as f: print('{}{}.{}'.format(word, i, img_format[1:])) f.write(img)
除了爬取动态页面,我们也完全可以用Selenium + Headless Chrome爬取其他页面。但是因为需要模拟浏览器,加载页面的各种文件,这种方法开销极大。所以如果不是必要,一般都使用开销更小的requests,毕竟绝大多数时候使用requests就能获取到我们想要的数据。另外,用单线程一张张获取图片很慢,如果有兴趣可以自己改成多线程来运行。