起因

半年来,给网盘使用的Microsoft E5开发者也过期了,现在才把瘫痪的网盘拉起来。与此同时瘫痪的还有随机图API。里边的壁纸都没了,而我一直都是找的2233图集。之前收藏的资源现在也过期了。
没办法,只能自己爬了,顺便当作曾经那篇烂尾文的续集。

教程

必备库:Selenium,Requests

如果不会安装Webdriver,请前往 Python Selenium 自动化详解 了解

爬取的网址: https://wallhaven.cc/search?q=id%3A46526


通过观察Url可得知,WallHaven的图片是动态加载的,所以我们需要往下拉,但是Selenium的下拉操作在此项目中不太方便,所以可以自己手动拉取,让程序sleep个十多秒,然后帮你拉回顶,目的就是为了加载所有图片。


通过使用Xpath Helper,我们可以找到所有有完整图像的链接,其语句就是:
//*[@id="thumbs"]/section/ul/li/figure/a/@href

但是在Selenium里的find_elements不能加上@href,如果你加了,你会看到这个玩意:

selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: The result of the xpath expression "//*[@id="thumbs"]/section/ul/li/figure/a/@href" is: [object Attr]. It should be an element.

所以你应该去掉,就是这样//*[@id="thumbs"]/section/ul/li/figure/a

接下来就是正常的点击到新标签页处理或者是获取href重新get。鉴于后者较为简单,不做赘述。重点讲前者。

为了控制新标签页,我们得先保存当前窗口的句柄,一会方便切回来。
currentHandle = driver.current_window_handle
在click操作后,driver.switch_to.window(driver.window_handles[-1])切换到最后一个窗口,也就是新打开的窗口,图片详情页。
最后通过driver.switch_to.window(currentHandle)切回。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
import requests

driver = webdriver.Chrome()
driver.get("https://wallhaven.cc/search?q=id%3A46526")

currentHandle = driver.current_window_handle
num = 1

time.sleep(15)

js = "var q=document.documentElement.scrollTop=0"
driver.execute_script(js)

eles = driver.find_elements(By.XPATH, '//*[@id="thumbs"]/section/ul/li/figure/a')
for ele in eles:
ele.click()
driver.switch_to.window(driver.window_handles[-1])
time.sleep(1)
src = driver.find_element(By.XPATH, '//*[@id="wallpaper"]').get_attribute("src")
with open(f"{num}.jpg", mode="wb") as f:
source = requests.get(src).content
f.write(source)
print("finish", src)
num += 1
driver.close()
driver.switch_to.window(currentHandle)

这个代码比较个性化,只针对此项目。如果想自己使用,需要稍微更改一下。