【网络爬虫】微信公众号采集

# WeixinCrawler

根据搜狗搜索 关键词采集 微信公众号和相应推文

采集策略:深度搜索采集

核心代码:

package main;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.Set;

import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.yaml.snakeyaml.util.UriEncoder;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

import model.HtmlParserTool;
import model.LinkFilter;

/**
 *
 * @ClassName: crawlWeixinMain
 * @Description: 搜狗微信采集
 * @author zeze
 * @date 2017年4月1日 下午2:50:26
 *
 */
public class crawlWeixinMain {
	private static Logger logger = Logger.getLogger(crawlWeixinMain.class);
	private static WebClient webClient;
	private static String host = "http://weixin.sogou.com/";
	private static String savePath = "f:/saveWeixin/";
	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
	private static int sleepTime = 8000;
	private static int randomTime = 3000;

	public static void main(String[] args) {
		String keyword = "xyzqfzfgs";
		int type = 2;// 1表示采集公众号,2表示采集文章
		if (type == 1)
			searchWeixinAccounts(keyword);
		else if (type == 2)
			searchWeixinArticles(keyword);
	}

	/**
	 * 初始化webclient header
	 */
	private static WebClient getWebClient() {
		WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);
		webClient.getOptions().setTimeout(20000);
		webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
		webClient.getOptions().setThrowExceptionOnScriptError(false);
		webClient.getOptions().setCssEnabled(false);
		// webClient.getOptions().setJavaScriptEnabled(false);
		webClient.addRequestHeader("User-Agent",
				"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36");
		webClient.addRequestHeader("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
		webClient.addRequestHeader("Accept-Language", "zh-CN,zh;q=0.8");
		webClient.addRequestHeader("Accept-Encoding", "gzip, deflate, sdch");
		webClient.addRequestHeader("Connection", "keep-alive");
		webClient.addRequestHeader("Upgrade-Insecure-Requests", "1");
		webClient.addRequestHeader("Cache-Control", "max-age=0");
		webClient.addRequestHeader("Host", "weixin.sogou.com");
		return webClient;
	}

	/**
	 * @Title: searchWeixinAccounts 根据关键词搜索微信公众号
	 */
	private static void searchWeixinAccounts(String keyword) {
		keyword = UriEncoder.encode(keyword);
		System.out.println("关键词:" + keyword);
		String url = "http://weixin.sogou.com/weixin?type=1&s_from=input&query=" + keyword
				+ "&ie=utf8&_sug_=n&_sug_type_=";
		// logger.info(url);
		WebClient webClient = getWebClient();
		HtmlPage page = null;
		try {
			page = webClient.getPage(url);
			Thread.sleep(sleepTime + new Random().nextInt(randomTime));
		} catch (FailingHttpStatusCodeException e) {
			logger.error(e);
		} catch (MalformedURLException e) {
			logger.error(e);
		} catch (IOException e) {
			logger.error(e);
		} catch (InterruptedException e) {
			logger.error(e);
		}
		HtmlParserTool htmlparser = new HtmlParserTool();
		// System.out.println(page.asXml());

		// 保存该页面page.asXml
		savePage(page.asXml(), keyword, 1, 0);

		Set<String> links = htmlparser.extracLinksByBody(page.asXml(), url, new LinkFilter() {
			public boolean accept(String url) {
				return true;
			}
		}, "utf-8");

		webClient.addRequestHeader("Host", "mp.weixin.qq.com");// 重新设置头文件
		for (String link : links) {

			if (link.contains("/mp.weixin.qq.com/profile")) {// 抽取得到一个微信公众号
				link = link.replaceAll("&", "&");
				System.out.println("搜索得到的公众号URL:" + link);
				try {
					page = webClient.getPage(link);
					Thread.sleep(sleepTime + new Random().nextInt(randomTime));
				} catch (FailingHttpStatusCodeException e) {
					logger.error(e);
				} catch (MalformedURLException e) {
					logger.error(e);
				} catch (IOException e) {
					logger.error(e);
				} catch (InterruptedException e) {
					logger.error(e);
				}
				// System.out.println(page.asXml());

				// 保存该页面page.asXml
				savePage(page.asXml(), keyword, 1, 1);

				int indexMsgList = page.asXml().indexOf("var msgList =");
				int indexSeajs = page.asXml().indexOf("seajs.use(");
				if (indexMsgList != -1 && indexSeajs != -1) {
					String msgList = page.asXml().substring(indexMsgList + 13, indexSeajs - 10);
					// System.out.println(msgList);
					try {
						JSONObject obj = new JSONObject(msgList);
						String listStr = obj.getString("list");
						// System.out.println("listStr:" + listStr);
						JSONArray listArray = new JSONArray(listStr);
						// System.out.println("list size=" +
						// listArray.length());
						for (int i = 0; i < listArray.length(); i++) {
							JSONObject listObj = listArray.getJSONObject(i);
							String app_msg_ext_info_Str = listObj.getString("app_msg_ext_info");
							// System.out.println("app_msg_ext_info_Str : " +
							// app_msg_ext_info_Str);

							JSONObject appObj = new JSONObject(app_msg_ext_info_Str);
							String appUrlStr = "http://mp.weixin.qq.com/"
									+ appObj.getString("content_url").replaceAll("&", "&");
							;
							String appTitleStr = appObj.getString("title");
							System.out.println(i + " app_Title:" + appTitleStr + " " + appUrlStr);

							try {
								page = webClient.getPage(appUrlStr);
								Thread.sleep(sleepTime + new Random().nextInt(randomTime));
							} catch (FailingHttpStatusCodeException e) {
								logger.error(e);
							} catch (MalformedURLException e) {
								logger.error(e);
							} catch (IOException e) {
								logger.error(e);
							} catch (InterruptedException e) {
								logger.error(e);
							}
							// System.out.println(page.asXml());
							// 保存该页面page.asXml
							savePage(page.asXml(), keyword, 1, 2);

							String multi_app_msg_item_list_Str = appObj.getString("multi_app_msg_item_list");
							// System.out.println("multi_app_msg_item_list_Str :
							// "+multi_app_msg_item_list_Str);
							JSONArray multiArray = new JSONArray(multi_app_msg_item_list_Str);
							// System.out.println("multi size=" +
							// multiArray.length());
							for (int j = 0; j < multiArray.length(); j++) {
								JSONObject multiObj = multiArray.getJSONObject(j);
								String multiUrl = "http://mp.weixin.qq.com"
										+ multiObj.getString("content_url").replaceAll("&", "&");
								String multiTitle = multiObj.getString("title");
								System.out.println(j + " multi_Title" + multiTitle + " " + multiUrl);
								try {
									page = webClient.getPage(multiUrl);
									Thread.sleep(sleepTime + new Random().nextInt(randomTime));
								} catch (FailingHttpStatusCodeException e) {
									logger.error(e);
								} catch (MalformedURLException e) {
									logger.error(e);
								} catch (IOException e) {
									logger.error(e);
								} catch (InterruptedException e) {
									logger.error(e);
								}
								// System.out.println(page.asXml());
								// 保存该页面page.asXml
								savePage(page.asXml(), keyword, 1, 2);
							}
						}

					} catch (JSONException e) {
						System.out.println(e);
					}
				} else {
					logger.error("异常页面:" + page.asXml());
				}

			}
		}

	}

	/**
	 * @Title: searchWeixinArticles 根据关键词搜微信文章
	 */
	private static void searchWeixinArticles(String keyword) {
		keyword = UriEncoder.encode(keyword);
		System.out.println("关键词:" + keyword);
		String url = "http://weixin.sogou.com/weixin?type=2&s_from=input&query=" + keyword
				+ "&ie=utf8&_sug_=n&_sug_type_=";
		WebClient webClient = getWebClient();
		HtmlPage page = null;
		try {
			page = webClient.getPage(url);
//			Thread.sleep(sleepTime + new Random().nextInt(randomTime));
		} catch (FailingHttpStatusCodeException e) {
			logger.error(e);
		} catch (MalformedURLException e) {
			logger.error(e);
		} catch (IOException e) {
			logger.error(e);
		}
//		} catch (InterruptedException e) {
//			logger.error(e);
//		}
		HtmlParserTool htmlparser = new HtmlParserTool();
		// System.out.println(page.asXml());

		// 保存该页面page.asXml
		savePage(page.asXml(), keyword, 2, 0);

		Set<String> links = htmlparser.extracLinksByBody(page.asXml(), url, new LinkFilter() {
			public boolean accept(String url) {
				return true;
			}
		}, "utf-8");

		webClient.addRequestHeader("Host", "mp.weixin.qq.com");// 重新设置头文件
		for (String link : links) {
			if (link.contains("/mp.weixin.qq.com/s?")) {// 抽取得到一个微信公众号
				link = link.replaceAll("&", "&");
				System.out.println("搜索得到的文章URL:" + link);
				logger.info("搜索得到的文章URL:" + link);
				try {
					page = webClient.getPage(link);
					Thread.sleep(sleepTime + new Random().nextInt(randomTime));
				} catch (FailingHttpStatusCodeException e) {
					logger.error(e);
				} catch (MalformedURLException e) {
					logger.error(e);
				} catch (IOException e) {
					logger.error(e);
				} catch (InterruptedException e) {
					logger.error(e);
				}
				// System.out.println(page.asXml());

				// 保存该页面page.asXml
				savePage(page.asXml(), keyword, 2, 1);
			}
		}

	}

	/**
	 * 保存目录:关键词/采集时间/type/deep/FormatDate.html 根据关键词采集深度和采集类型保存页面
	 *
	 * @Title: savePage
	 * @param @param
	 *            page 页面
	 * @param @param
	 *            type 微信采集Type 1表示公众号,2表示采集文章
	 * @param @param
	 *            deep 根据采集深度保存页面
	 * @param @param
	 *            keyword 关键词
	 * @return void 返回类型
	 */
	private static void savePage(String page, String keyword, int type, int deep) {

		long start = System.currentTimeMillis();
		String path = null;
		File file2 = null;
		SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyyMMddHH");

		String outputpath = savePath + "KeyWord-" + keyword + "/";
		file2 = new File(outputpath);
		if (!file2.exists())
			file2.mkdirs();
		outputpath = outputpath + "Time-" + dateFormat1.format(new Date()) + "/";
		file2 = new File(outputpath);
		if (!file2.exists())
			file2.mkdirs();
		outputpath = outputpath + "Type-" + type + "/";
		file2 = new File(outputpath);
		if (!file2.exists())
			file2.mkdirs();
		outputpath = outputpath + "Deep-" + deep + "/";
		file2 = new File(outputpath);
		if (!file2.exists())
			file2.mkdirs();

		path = new String(outputpath + dateFormat.format(new Date()) + "_D." + deep + "_T" + type + ".html");

		file2 = new File(path);

		FileOutputStream outputStream;

		try {
			outputStream = new FileOutputStream(file2);
			outputStream.write(page.getBytes());
			start = System.currentTimeMillis();
			outputStream.close();
		} catch (FileNotFoundException e) {

		} catch (IOException e) {

		}
	}

}

Github地址:

https://github.com/chzeze/WeixinCrawler

时间: 2024-08-06 07:13:16

【网络爬虫】微信公众号采集的相关文章

微信公众号文章采集器

今天讨教大叔给大家聊聊什么是微信公众号文章采集器?微信公众号文章采集器的用处在哪里? 首先简单的介绍下微信公众号文章采集器:它是由讨教平台开发,专门服务于中小型互联网企业的一款内容价值输出系统.帮助中小型企业在文章发布,内容输出,大量提高了员工工作效率的以及企业的运营成本. 在采集系统中,我们可以把所有的微信公众号,只需要你手动输入 你想采集公众号的名称输入采集系统上,即可快速的帮助你完成此公众号的内容全部采集.采集过来的文章,您可以选择修改标题和内容,以及过滤掉垃圾文章. 我们讨教平台测试过:

微信公众号 文章的爬虫系统

差不多俩个星期了吧,一直在调试关于微信公众号的文章爬虫系统,终于一切都好了,但是在这期间碰到了很多问题,今天就来回顾一下,总结一下,希望有用到的小伙伴可以学习学习. 1.做了俩次爬虫了,第一次怕的凤凰网,那个没有限制,随便爬,所以也就对自动化执行代码模块放松了警惕,觉得挺简单的,但是其实不是这样的,我被这个问题困扰了好几天,差不多4天的一个样子,因为搜狗做的限制,同一个ip获取的次数多了,首先是出现验证码,其次是就是访问限制了,直接就是不能访问,利用 request得到的就是访问次数过于频繁,这

基于搜狗搜索的微信公众号爬虫实现(C#版本)

Author: Hoyho Luo Email: [email protected] Source Url:http://here2say.me/11/ 转载请保留此出处 本文介绍基于搜狗的微信公众号定向爬虫,使用C#实现,故取名WeGouSharp.本文中的项目托管在Github上,你可以戳WeGouSharp获取源码,欢迎点星.关于微信公共号爬虫的项目网上已经不少,然而基本大多数的都是使用Python实现 鉴于鄙人是名.NET开发人员,于是又为广大微软系同胞创建了这个轮子,使用C#实现的微信

Python爬虫实现的微信公众号文章下载器

平时爱逛知乎,收藏了不少别人推荐的数据分析.机器学习相关的微信公众号(这里就不列举了,以免硬广嫌疑).但是在手机微信上一页页的翻阅历史文章浏览,很不方便,电脑端微信也不方便. 所以我就想有什么方法能否将这些公众号文章下载下来.这样的话,看起来也方便.但是网上的方法要么太复杂(对于我这个爬虫入门新手来说),要么付费. 但我的需求其实却很简单--"方便的查找 / 检索 / 浏览相关公众号的任意文章",所以,一番学习检索后,上手做了一个小工具(打包成可执行文件了),虽然方法和代码相当简单,但

第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号

第三百三十节,web爬虫讲解2-urllib库爬虫-实战爬取搜狗微信公众号 封装模块 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib from urllib import request import json import random import re import urllib.error def hq_html(hq_url): """ hq_html()封装的爬虫函数,自动启用了用户代理和ip

[Python爬虫] 之十五:Selenium +phantomjs根据微信公众号抓取微信文章

借助搜索微信搜索引擎进行抓取 抓取过程 1.首先在搜狗的微信搜索页面测试一下,这样能够让我们的思路更加清晰 在搜索引擎上使用微信公众号英文名进行“搜公众号”操作(因为公众号英文名是公众号唯一的,而中文名可能会有重复,同时公众号名字一定要完全正确,不然可能搜到很多东西,这样我们可以减少数据的筛选工作, 只要找到这个唯一英文名对应的那条数据即可),即发送请求到'http://weixin.sogou.com/weixin?type=1&query=%s&ie=utf8&_sug_=n&

九 web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解

封装模块 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib from urllib import request import json import random import re import urllib.error def hq_html(hq_url): """ hq_html()封装的爬虫函数,自动启用了用户代理和ip代理 接收一个参数url,要爬取页面的url,返回html源码 "

从Python爬虫到SAE云和微信公众号:二、新浪SAE上搭建微信服务

目的:用PHP在SAE上搭建一个微信公众号的服务器. 1.申请一个SAE云账号 SAE申请地址:http://sae.sina.com.cn/  可以使用微博账号登陆,SAE是新浪的云服务,时间也比较长了,功能比较多. 特点:免费使用,对于学习者而言已经够用了,长时间用充点云豆也花不了多少钱(最低每天10云豆消费),几十块钱(1元=100云豆)玩一年还是可以的. AWS:如果使用aws免费的空间,很容易用超免费额度,而且用超了额度不会停止,而是从信用卡扣费,以美元计价价格对于学习者而言非常昂贵!

贴吧无耻霸屏技术! 几万阅读量的微信公众号都偷偷的使用它

有时候发现!不是自己要专注一件事情就会有结果,而是你一开始做的项目或者做的事情能让你有回报,并且你能继续的做下去.最近我总觉得死磕是一个不应该说的词!我们死磕是因为我们看到希望,我们的付出有回报!如果一件事你死磕了2个月没有任何希望,激情都没有了!还是放弃吧!我开始专注于贴吧完全是我的付出得到了回报!然后开始专心的做!经常凌晨的时候在贴吧打转!然后偶遇发现了另外一个更好的霸屏技术!这个方法更加的简单暴力,更加的快速.基本都不用考虑防删处理!直接就是任性的狂发上去的!! 这个也是机缘巧合发现的!然