获取bing首页的每日一图
阅读原文时间:2022年03月22日阅读:1

从必应(bing)首页抓取他的每日一图

以前上学时,曾经用python写过一个每天抓取bing每日一图的小工具。

现在想用java来重构一下。

抓取图片的思路

首先获取网页源码

从网页源码中,我们可以找到图片的下载链接以及图片的描述信息。

利用下载链接我们就能得到相应的图片。

使用python实现抓取

我们使用python中的requests库来获取网页源码,然后利用正则表达式从网页源码中搜索出图片的下载链接。

res = requests.get(url) #获取网页源码,并利用正则表达式找到与bing每日一图有关的参数
pattern = re.compile(r"(\/th\?id=(.+?)\.jpg)")
# pattern = re.compile(r"\/th\?id=(.+)(\.jpg)") 

result = pattern.search(res.text) #从源码中获取bing大图的图片链接
imgLinkParam = result.group(0).split("&")
imgDownloadUrl = url+"&".join(imgLinkParam)

拿到图片的下载地址后,还需要从网页中找出图片的标题。

这里我们使用BeautifulSoup库来解析网页。

找到所有class="title"的a节点,取找到的a第一个节点,他的内容就是图片的标题。

soup = BeautifulSoup(res.text,'lxml') #使用bs4来解析对应的html文件
#print(soup)
# imageInfo = soup.find_all(name="a",attrs={"id":"sh_cp","class":"sc_light"})
imageInfo = soup.find_all(name="a", attrs={"class":"title"})
imageDescription=imageInfo[0].contents[0] #获取对图片的描述

最后我们根据图片链接,将图片下载到本地

pictureData = requests.get(imgDownloadUrl) #根据下载链接获取图片数据
with open(imgName,"wb") as f:
    f.write(pictureData.content)
    f.flush()
    log_write(logName,"图片保存成功")

如何使用java重构代码

思路与前面python的实现大致相同,先获取bing首页html内容,然后解析html,获取需要的内容。然后下载图片

首先,发送请求与根据链接下载图片文件需要构造http请求,这里我们使用java 11自带的HttpClient来发送http请求。

HttpClient的使用参考Java11新特性之HttpClient小试牛刀_java_脚本之家 (jb51.net)

获取并首页html内容

使用HttpClient,首先利用建造者(builder)模式创建一个HttpRequest,然后创建一个HttpClient来发送http请求,并指定响应Response的类型。

HttpRequest.Builder requestBuilder = HttpRequest.newBuilder();
requestBuilder.uri(new URI(baseUrl));
requestBuilder.GET();
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofString());
String html = response.body();
解析html

我们使用jsoup库来对获取的html进行解析。然后使用select方法,按照类似jquery的操作方式,获取html中指定的节点。

我们要获取的与图片有关的信息包括:图片的标题(title),下载地址,图片描述(Description),图片的版权信息

//解析html
Document document = Jsoup.parse(html);
//获取图片title
Element element = document.select("a[class=title]").first();
if(null == element){
    System.out.println("没有获取到图片标题");
    return;
}
String pictureTitle = element.text();
System.out.println(pictureTitle);
//获取图片下载地址
element = document.select("link[rel=preload]link[id=preloadBg]").first();
assert element != null;
String pictureDownloadUrl = element.attr("href");
System.out.println(pictureDownloadUrl);
//获取图片描述
element = document.select("meta[property=og:description]").first();
assert element != null;
System.out.println(element.attr("content"));

//获取图片的版权信息
element = document.select("div[class=copyright]div[id=copyright]").first();
assert element != null;
System.out.println(element.text());
图片下载

拿到图片链接之后,可以使用httpClient来下载图片到本地

在java11中,httpClient支持异步请求,这里使用异步请求来下载图片。

//下载图片
LocalDate date = LocalDate.now();
//构造图片存放的本地路径
String imgLocalPath = basePath+ date.toString() + imageType; 

requestBuilder.uri(new URI(pictureDownloadUrl))
                .GET();
CompletableFuture<Path> future =  client.sendAsync(requestBuilder.build(), HttpResponse.BodyHandlers.ofFile(Paths.get(imgLocalPath)))
        .thenApply(HttpResponse::body);
System.out.println(future.get());//get得到的是图片在本地的存放路径

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章