爬虫基本理解
通俗一点,爬虫
是用来快速、批量获取我们在网络需要的东西,过滤掉不需要的东西,比如我可以爬一个网站的所有图片省的一张一张去保存,也可以爬其他数据来做研究、统计、数据分析,即是:
(1) 对抓取目标的描述或定义;
(2) 对网页或数据的分析与过滤;
(3) 对URL的搜索策略。
很多语言都可以做爬虫,在这里记录JAVA做一个简单的爬虫,等以后学会其他语言了再用其他语言做爬虫,哈哈…
实现爬虫需要
知识点
- 简单HTML、CSS、JS等前端知识
- 正则表达式(很重要,用于过滤不需要的信息)
- JAVA语言知识(可换成其他语言)
参数
- 首先你要给它一个种子链接
URL
- 在种子链接的页面查找其他的URL,重复1步骤
- 有链接有页面,然后你可以在页面中查找需要的内容
简单爬虫代码
在这里做个示例:把网站https://www.baidu.com/home/news/data/newspage?nid=7953839918275534&n_type=0&p_from=1
图片全部down下来并保存到本地磁盘的操作。
JAVA基本方式
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| public class Reptile { public static String doGet(String urlStr) throws Exception { URL url; String html = ""; try { url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Accept", "text/html"); connection.setRequestProperty("Accept-Charset", "utf-8"); connection.setRequestProperty("Accept-Language", "en-US,en"); connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.160 Safari/537.22"); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setDoInput(true); connection.setDoOutput(true); if (connection.getResponseCode() == 200) { System.out.println("已连接,正在解析。。。。。。"); InputStream in = connection.getInputStream(); html = StreamTool.inToStringByByte(in); } else { System.out.println(connection.getResponseCode()); } } catch (Exception e) { e.printStackTrace(); throw new Exception("get请求失败"); } return html; }
public static void main(String[] args) throws Exception { Reptile reptile = new Reptile() String htmlStr = Reptile.doGet("https://www.baidu.com/home/news/data/ newspagenid=7953839918275534&n_type=0&p_from=1");
File f = new File("E://imgs"); if (!f.exists()) { f.mkdirs(); }
Pattern pattern = Pattern.compile("<img.*src=(.*?)[^>]*?>"); Matcher matcher = pattern.matcher(htmlStr); System.out.println("正在下载"); while (matcher.find()) { String imgs = matcher.group(); Matcher srcMatcher = Pattern.compile("https:\"?(.*?)(\"|>|\\s+)").matcher(imgs); while (srcMatcher.find()) { String src = srcMatcher.group().substring(0,srcMatcher.group().length() - 1); System.out.println(src); String imageName = src.substring(src.lastIndexOf("/") + 1,src.length()); reptile.downLoad(src, imageName); } } } public void downLoad(String src, String imageName) throws Exception { URL url = new URL(src); URLConnection uri = url.openConnection(); InputStream is = uri.getInputStream(); OutputStream os = new FileOutputStream(new File("E://imgs", imageName)); byte[] buf = new byte[1024]; int len = 0; while ((len = is.read(buf)) != -1) { os.write(buf, 0, len); } os.close(); is.close(); } }
|
JAVA基本方法主要是利用JAVA中的正则表达式匹配我们我需要的元素,然后再进行其他操作。简单、粗暴。
Jsoup
是一个 Java 的开源HTML解析器,可直接解析某个URL地址、HTML文本内容。同时提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。可以直接使用DOM或者JQuery方法和表达式取出数据。
需要下载JAR包,下载地址:点我
Jsoup API
:详见:http://www.open-open.com/jsoup/
工具类StreamTool :将byte对象转化为String对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class StreamTool {
public static String inToStringByByte(InputStream in) throws Exception { ByteArrayOutputStream outStr = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; StringBuilder content = new StringBuilder(); while ((len = in.read(buffer)) != -1) { content.append(new String(buffer, 0, len, "UTF-8")); } outStr.close(); return content.toString(); } }
|
基本实现类Reptile
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| public class Reptile { public static String doGet(String urlStr) throws Exception { URL url; String html = ""; try { url = new URL(urlStr); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Accept", "text/html"); connection.setRequestProperty("Accept-Charset", "utf-8"); connection.setRequestProperty("Accept-Language", "en-US,en"); connection.setRequestProperty("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.160 Safari/537.22"); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setDoInput(true); connection.setDoOutput(true); if (connection.getResponseCode() == 200) { System.out.println("已连接,正在解析。。。。。。"); InputStream in = connection.getInputStream(); html = StreamTool.inToStringByByte(in); } else { System.out.println(connection.getResponseCode()); } } catch (Exception e) { e.printStackTrace(); throw new Exception("get请求失败"); } return html; }
public static void main(String[] args) throws Exception { URL url ; InputStream is = null; OutputStream os = null; String urlStr = "https://www.baidu.com/home/news/data/newspage?nid=7953839918275534&n_type=0&p_from=1"; String htmlStr = Reptile.doGet(urlStr); Document doc = Jsoup.parse(htmlStr);
File f = new File("E://imgs"); if (!f.exists()) { f.mkdirs(); } Elements pngs = doc.select("img[src]");
int i = 1; for (Element e : pngs) { String src = e.attr("src"); String imageName = src.substring(src.lastIndexOf("/") + 1, src.length());
System.out.println("正在下载第" + i + "张图片:"+ imageName); URL url = new URL(src); URLConnection uri = url.openConnection(); is = uri.getInputStream(); os = new FileOutputStream(new File("E://imgs",imageName)); byte[] buf = new byte[1024]; int len = 0; while ((len = is.read(buf)) != -1) { os.write(buf, 0, len); } i++; } os.close(); is.close(); System.out.println("共有" + (i-1) + "张图片。"); } }
|
总结
在这里只做个一个简单的爬虫示例,通过两种方式的比较后,发现Jsoup更佳。
JAVA
基本的方式能用正则表达式来匹配所需要的元素,灵活性不高。
Jsoup
这个强大的工具提供了DOM和JQuery方法,可以直接操作节点,同时也支持正则表达式,更加的灵活、省力,同时选择性、可玩性和扩展性更高。Jsoup更多的方法可以查看Jsoup的API。
现在已经有很多开源的爬虫的框架供我们选择,比如webmagic、Heritrix等,可以适当选择。
附
还有一种更为简单强大的方式,在Linux环境
下,利用wget命令
只需要一行命令就可以实现以上功能。
1
| wget -m -H -nd -l 1 -t 1 -A .jpg,.png,.jpeg,.JPEG -e robots=off -P /opt/download --no-check-certificate https://www.baidu.com/home/news/data/newspage?nid=7953839918275534&n_type=0&p_from=1
|
在下篇博客写一下Linux的基本命令。