以前上学时,曾经用python写过一个每天抓取bing每日一图的小工具。
现在想用java来重构一下。
首先获取网页源码
从网页源码中,我们可以找到图片的下载链接以及图片的描述信息。
利用下载链接我们就能得到相应的图片。
我们使用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,"图片保存成功")
思路与前面python的实现大致相同,先获取bing首页html内容,然后解析html,获取需要的内容。然后下载图片
首先,发送请求与根据链接下载图片文件需要构造http请求,这里我们使用java 11自带的HttpClient来发送http请求。
HttpClient的使用参考Java11新特性之HttpClient小试牛刀_java_脚本之家 (jb51.net)
使用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();
我们使用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得到的是图片在本地的存放路径