java爬取头条文章中名字图片

背景描述:

       前段时间,我哥让我给侄女想一个好名字,作为一个工科生,这倒有点难倒我了。隐约记得以前刷头条的时候刷到过一些好听的名字,于是便去搜了一下。这一搜不要紧,接下来给我推送的都是关于这方面的文章,而我就毫不客气地全都收藏了。刚好这两天闲下来了,便想着把保存下来。但一看,都收藏了几十篇文章,且都是图片,如果一篇篇地去看,然后下载,这无疑就是搬砖。这让我这种懒人无疑是不能接受了。于是便想着写一个爬虫吧,把全部都爬下来。

       当然,有的砖必须得搬,比如各个文章的URL地址,这个以目前的能力还不能智能获取。首先手动获取了各篇文章的URL地址,如下图所示。

                                

在得到文章的URL之后,便开始文章中各个图片爬取工作了。话不多说,直接放码。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import org.apache.commons.io.FileUtils;

import cn.cxd.tools.FileTools;

public class DownLoadToutiaoPicture {

	public static void main(String[] args) throws Exception {

		String srcPath = "D:/name/url.txt";// 保存了各个文章URL地址
		String dstPath = "D:/name/content.txt";// 保存了文章中各个图片的URL
		String dstDir = "D:/name/";// 最终图片存放的目录
		File srcFile = new File(srcPath);
		File dstFile = new File(dstPath);

		BufferedReader br = new BufferedReader(new FileReader(srcFile));
		BufferedWriter bw = new BufferedWriter(new FileWriter(dstFile));

		String line = null;

		while ((null) != (line = br.readLine())) {
			getContent(bw, line);
		}

		line = null;

		BufferedReader br1 = new BufferedReader(new FileReader(dstFile));
		ArrayList<String> totalPicUrlList = new ArrayList<>();// 存放各个图片的URL
		while ((null) != (line = br1.readLine())) {
			ArrayList<String> tmpList = parse(line);// 一篇文章中图片的URL地址。
			totalPicUrlList.addAll(tmpList);// 加入到总list里面。
		}

		for (int index = 0; index < totalPicUrlList.size(); index++) {
			// 使用了Apache第三方的common io,既然别人把轮子都造好了,那就发扬拿来主义吧!哈哈哈。。。
			FileUtils.copyURLToFile(new URL(totalPicUrlList.get(index)), new File(dstDir + index + ".jpg"));
		}

		FileTools.close(br1, bw, br);
	}

	/**
	 * 根据文章的URL地址获取各个图片的URL。通过分析网页的源码可知,一个图片的URL完整地址可能分行显示。而全部图片的URL都包含在articleInfo里面,
	 * 因此,本文的方案是把articleInfo里面的内容全部获取到本地,然后再解析,即后面的parse()函数。
	 * 
	 * @param bw
	 * @param line
	 *            文章的URL地址链接
	 * @throws Exception
	 */
	private static void getContent(BufferedWriter bw, String line) throws Exception {

		URL url = new URL(line);
		// 头条做了反爬机制,必须将程序伪装成浏览器访问才行。
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestMethod("GET");
		conn.setRequestProperty("user-agent",
				"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36");

		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

		// 将articleInfo里面的内容组装成一行,方便后面的解析工作。
		StringBuilder sb = new StringBuilder();
		boolean flag = false;
		// 这里建议不要用while((null) !=
		// (line=br.readLine()))来做,极有可能还没有读到articleInfo时就为空,导致程序退出。
		for (int i = 0; i < 2000; i++) {
			String input = br.readLine();

			if (null != input) {
				System.out.println(input);
				if (input.contains("articleInfo")) {
					System.out.println(input);
					flag = true;
				}

				if (flag == true) {
					sb.append(input);
					System.out.println(input);
				}

				if (input.contains("groupId")) {// groupId为articleInfo结束后的第一行内容,读到这表示articleInfo内容已经读完,则将i置为200以退出循环。
					i = 2000;
				}
			}
		}
		bw.write(sb.toString());

		bw.newLine();
		sb = new StringBuilder();
		FileTools.close(br);
	}

	/**
	 * 解析出里面的URL地址,存入list并返回。
	 * 
	 * @param line
	 *            上面提到的articleInfo里面的内容。
	 * @return
	 */
	private static ArrayList<String> parse(String line) {

		int len = line.length();
		char[] ch = line.toCharArray();

		StringBuilder sb = new StringBuilder();

		ArrayList<String> picUrlList = new ArrayList<>();
		for (int i = 0; i < len - 4; i++) {
			String tmp = line.substring(i, i + 4);
			if (tmp.equals("http")) {
				for (int j = i; j < len; j++) {
					if (ch[j] != '&') {
						sb.append(ch[j]);
					} else {
						j = len;
					}
				}

				picUrlList.add(sb.toString());
				sb = new StringBuilder();
			}

		}
		return picUrlList;
	}
}

关于遇到的坑已经在代码注释中做了说明。

另外,在程序最后也出现了异常,如下图所示:

这个还得日后再去深扒。

最后爬取的结果如下图所示:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值