这是voidAlex原创的第三篇博文。
源码在我的GitHub
爬虫
上一篇博文介绍了如何模拟登录和解析JSON数据,这篇博文介绍怎么爬取不需要登录的网站的信息。
上一篇博文中关于爬虫的介绍可以点这里查看。
引入JSOUP
在pom.xml
中添加JSOUP依赖:
1 2 3 4 5
| <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.10.2</version> </dependency>
|
JSOUP是一款Java的HTML解析库,可以解析HTML中的文本内容。它的官网地址是https://jsoup.org/。
查看网页源码
好了,要干正事了。Google一下妹子图,找到这两个网站:http://jandan.net/ooxx,http://www.youmzi.com/tuinvlang.html.先看第一个,它的源码长这样:
我们要找的是所有的img标签里的URL,然后把它下载下来。但是这样似乎只能爬取单个页面的妹子图?所以我们还要找到下一页的URL:
恩,找到了。开始写代码吧!
downloadImage方法
首先写一个下载图片的方法,该方法传入图片的URL和要写入的路径,然后将文件写入本地。需要调用java.net
包中的一些方法。
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
| public static boolean downloadImage(String imageUrl, String path) { try { String filePath = path + imageUrl.substring(imageUrl.lastIndexOf("/")); URL url = new URL(imageUrl); HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setConnectTimeout(10000); connection.setReadTimeout(10000); InputStream in = connection.getInputStream(); File file = new File(filePath); FileOutputStream out = new FileOutputStream(file); int i = 0; while ((i = in.read()) != -1){ out.write(i); } System.out.println(imageUrl + "下载成功"); out.close(); in.close(); return true; }catch (Exception e){ System.out.println(imageUrl + "下载失败"); return false; } }
|
需要注意的是要设置超时的时间,要不然会导致很多的图片下载失败。
解析HTML
接下来我们需要理一理这个爬虫的思路:
- 打开这个网页。获取到网页所有图片的URL,然后遍历这些URL去下载图片;
- 当遍历结束后,去找下一页的URL,然后执行1;
- 直到找不到下一页的URL为止。
煎蛋妹子图
首先用jsoup
中的方法获取到网页并且得到Document对象:
1 2
| Document doc = null; doc = Jsoup.connect(url).get();
|
获得所有的img标签:
1
| Elements elements = doc.getElementsByTag("img");
|
遍历这些标签并且下载:
1 2 3 4 5 6 7
| for (Element element : elements){ String imgSrc = element.attr("abs:src"); if (downloadImage(imgSrc, path)){ count ++; } }
|
获取下一页的地址,如果没有则退出循环:
1 2 3 4 5 6 7
| try { url = doc.getElementsByClass("previous-comment-page").get(0) .getElementsByTag("a").attr("abs:href"); }catch (Exception e){ System.out.println("没链接了~"); break; }
|
大功告成!
优妹子
第二个网站的略微复杂一点,上方有导航栏,每一页有若干个专题,点击进去了才是大图。所以需要爬取的链接稍微多一点。
首先还是获取到网页并且得到Document对象:
1 2
| Document doc = null; doc = Jsoup.connect(url).get();
|
然后获得每一个二级页面(即专题)的URL,并放到一个List里面:
1 2 3 4 5
| Elements imageUrl = doc.getElementsByClass("tzpic3-mzindex").get(0).getElementsByTag("a"); ArrayList<String> urlList = new ArrayList<String>(); for (Element element : imageUrl){ urlList.add(element.attr("abs:href")); }
|
对于List里的每一个URL,去找它每一个的img标签并且获取下一页的URL:
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 30 31 32 33 34 35 36 37 38 39 40
| for (String s : urlList){ String next = s; while (true){ try { doc = Jsoup.connect(next).get(); }catch (IOException e){ System.out.println(url + "请求失败"); } Element e = doc.getElementsByClass("arpic").get(0); Elements elements = e.getElementsByTag("img"); for (Element element : elements){ String imgSrc = element.attr("abs:src"); if (downloadImage(imgSrc, path)){ count ++; } } String tmp = next; try { Elements nextPage = doc.getElementsByClass("jogger2").get(0).getElementsByTag("a"); next = null; for (Element element : nextPage){ if (element.text().equals("下一页")){ next = element.attr("abs:href"); } } }catch (Exception ex){ System.out.println("没链接了~"); break; } if (next == null || tmp.equals(next)){ break; } } }
|
运行
1 2 3 4 5
| public static void main(String args[]) throws Exception{ String path = "image"; jiandan(path); youmeizi(path); }
|
跑了两个多小时终于跑完了,看一下战果:
恩,将近1w张。不说了,我先喝瓶营养快线去~