记一次批量定时抓取微信公众号文章的实现

  • 抓取前的说明和准备
    • 数据的抓取
    • 批量抓取
    • 定时抓取
    • 对爬虫防抓取机制的一些解决办法
    • 最后

抓取前的说明和准备

本次抓取的选择的语言是java,本文章不会将整个工程的全部代码全部贴出,只会提供核心代码和抓取思路的说明。

数据的抓取

抓取文章的来源为搜狗微信网站,网站如下图。

抓取的思路如下

  1. 一般抓取微信公众号的文章都是以微信公众号的id为关键字 ,我们可以通过url+ keyword的形式直接跳转到想要抓取公众号页面,keyword即为想要搜索微信公众号的名称或者是id;
// 搜狗微信搜索链接入口String sogou_search_url = "http://weixin.sogou.com/weixin?type=1&query="+ keyword + "&ie=utf8&s_from=input&_sug_=n&_sug_type_=";
  1. 为了避免网站对爬虫的初步拦截,我们可以使用Selenium (浏览器自动化测试框架)来伪装自己的爬虫,我们使用的chrome,这里需要注意自己的chrome版本与使用的webdriver的版本是对应的
       ChromeOptions chromeOptions = new ChromeOptions();// 全屏,为了接下来防抓取做准备chromeOptions.addArguments("--start-maximized");System.setProperty("webdriver.chrome.driver", chromedriver);WebDriver webDriver = new ChromeDriver(chromeOptions);
  1. 到达微信公众号列表页面,如下图,获取微信公众号链接。
              // 获取当前页面的微信公众号列表List<WebElement> weixin_list = webDriver.findElements(By.cssSelector("div[class='txt-box']"));// 获取进入公众号的链接String weixin_url = "";for (int i = 0; i <= weixin_list.size(); i++) {String weixin_name = weixin_list.get(i).findElement(By.cssSelector("p[class='tit']")).findElement(By.tagName("a")).getText();if (weixin_name.equals(keyword)) {weixin_url = weixin_list.get(i).findElement(By.cssSelector("p[class='tit']")).findElement(By.tagName("a")).getAttribute("href");break;}}webDriver.get(weixin_url);
  1. 到达微信公众号文章列表页面,如下图;

  2. 通过对网页元素的分析对微信文章相关信息进行抓取;

             // 获取微信文章列表List<WebElement> weixin_article_list = webDriver.findElements(By.cssSelector("div[class='weui_media_box appmsg']"));for (WebElement weixin_article : weixin_article_list) {// 获取文章缩略图urlString thumbNail = weixin_article.findElement(By.cssSelector("span[class='weui_media_hd']")).getAttribute("style").substring(23);String thumbNailUrl = thumbNail.substring(0,thumbNail.length() - 3);// 获取文章urlString articleUrl = "http://mp.weixin.qq.com"+ weixin_article.findElement(By.cssSelector("h4[class='weui_media_title']")).getAttribute("hrefs");// 获取文章简介String desc = weixin_article.findElement(By.cssSelector("p[class='weui_media_desc']")).getText();// 获取文章日期String dateString = weixin_article.findElement(By.cssSelector("p[class='weui_media_extra_info']")).getText();Date date = null;try {date = new SimpleDateFormat("yyyy年MM月dd日").parse(dateString);} catch (ParseException e) {// TODO 完成异常处理e.printStackTrace();}Date today = new Date();

批量抓取

批量抓取的实现是通过Spring Batch来实现的。Spring Batch 是一个轻量级的、完善的批处理框架,旨在帮助企业建立健壮、高效的批处理应用。
Spring Batch 分为Reader,Processor,Writer,Listener等几个部分。因为是进行批量抓取,所以可以新建一个稿件抓取历史列表来判断是否为新的稿件,从而判断是否进行抓取。


@Configuration
@EnableBatchProcessing
@EnableScheduling
public class WechatOfficialAccountsStoryImportBatchConfig {@Beanpublic WechatOfficialAccountsStoryReader<WechatLink> wechatOfficialAccountsStoryReader() throws BusinessException, IOException {return new WechatOfficialAccountsStoryReader<WechatLink>();}@Beanpublic ItemProcessor<LinkHolder<WechatLink>, NrStory> wechatOfficialAccountsStoryProcessor() {return new WechatOfficialAccountsStoryProcessor();}@Beanpublic ItemWriter<NrStory> wechatOfficialAccountsStoryWriter() {return new WechatOfficialAccountsStoryWriter();}@Beanpublic Job importStoryWechatOfficialAccountsJob(JobBuilderFactory jobs, StepBuilderFactory stepBuilderFactory) throws BusinessException, IOException {return jobs.get("importStoryWechatOfficialAccountsJob").incrementer(new RunIdIncrementer()).listener(listener(wechatOfficialAccountsStoryReader())).flow(importStoryWechatOfficialAccountsStep(stepBuilderFactory)).end().build();}@Beanpublic Step importStoryWechatOfficialAccountsStep(StepBuilderFactory stepBuilderFactory) throws BusinessException, IOException {return stepBuilderFactory.get("importStoryWechatOfficialAccountsStep").<LinkHolder<WechatLink>, NrStory> chunk(1).faultTolerant().skip(SkippingException.class).skip(BusinessException.class).skipLimit(100000).reader(wechatOfficialAccountsStoryReader()).processor(wechatOfficialAccountsStoryProcessor()).writer(wechatOfficialAccountsStoryWriter()).build();}@Beanpublic WechatOfficialAccountsStoryJobListener listener(WechatOfficialAccountsStoryReader<WechatLink> reader) {return new WechatOfficialAccountsStoryJobListener(reader);}
}

定时抓取

Spring Batch支持定时抓取,具体规则参考Scheduled。


@Scheduled(cron = "0 0 7,9,11,13,15,17,23 * * ?")public synchronized void executeWechatOfficialAccountsStoryImport() throws BusinessException, IOException {try {    long begin = System.currentTimeMillis();LOG.info("############## 微信公众号定时任务开始 ##############");Job importStoryJob = wechatOfficialAccountsConfig.importStoryWechatOfficialAccountsJob(jobs, stepBuilderFactory);JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis()).toJobParameters();JobExecution jobExecution = jobLauncher.run(importStoryJob,jobParameters); LOG.info("jobExecution" + jobExecution);long end = System.currentTimeMillis();LOG.info("##############微信公众号定时任务结束,共耗时:[" + (end-begin) / 1000 + "]秒##############");} catch (JobExecutionAlreadyRunningException e) {LOG.info("微信公众号文章导入发生错误!" + e.getLocalizedMessage());} }

对爬虫防抓取机制的一些解决办法

如果抓取的频率较高,抓取的时候页面会要求输入验证码,我也尝试过许多图片识别的jar包,效果并不是很好。我们采用的是第三方的打码平台,有的时候人工还是比智能更好。我们选择的打码平台是快若打码,其官网上有他的使用方法,他提供了一些第三方接口。识别验证码后输入,继续进行抓取。


// 获取当前网页的标题String title = webDriver.getTitle();while (title.contentEquals("请输入验证码")) {LOG.info("############## 微信公众号访问失败,需要输入验证码 ##############");LOG.info("############## 开始识别验证码 ##############");// 全屏截图File srcFile = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);Image src = Toolkit.getDefaultToolkit().getImage(srcFile.getPath());BufferedImage originalImage = WechatOfficialAccountStoryJobUtils.toBufferedImage(src);WebElement verify = webDriver.findElement(By.className("page_verify"));Point location = verify.getLocation();Dimension size = verify.getSize();// 截取验证码int getX = location.getX();int getY = location.getY();int getWidth = size.getWidth();int getHeight = size.getHeight();BufferedImage verifyImg = originalImage.getSubimage(getX + getWidth / 3, getY + getHeight / 3,getWidth / 2, getHeight / 3);// 验证码的名称和路径String dirName = "D:/verifyImg";File dir = new File(dirName);Date time = new Date();String verifyImgPath = dirName + "/" + time.getTime()+ ".jpg";// 验证码文件夹是否存在if (dir.exists()) {LOG.info("############## 目录已存在,无需创建 ##############");} else {LOG.info("############## 目录不存在,正在创建目录 ##############");if (dir.mkdirs()) {LOG.info("############## 目录创建成功 ##############");}}// 下载验证码try {ImageIO.write(verifyImg, "jpg",new File(verifyImgPath));} catch (IOException e) {// TODO 完成异常处理e.printStackTrace();}LOG.info("############## 验证码下载成功 ##############");// 识别验证码String ret = WechatOfficialAccountStoryJobUtils.createByPost(ruokuaiUsername, ruokuaiPassword,ruokuaiWeixintypeid, ruokuaiTimeout,ruokuaiSoftid, ruokuaiSoftkey,verifyImgPath);String verifyLetter = ret.substring(37, 41);LOG.info("############## 验证码识别成功 ,验证码为:##############");LOG.info(verifyLetter);// 输入验证码WebElement input = webDriver.findElement(By.id("input"));input.sendKeys(verifyLetter);WebElement bt = webDriver.findElement(By.id("bt"));bt.click();// 刷新页面webDriver.navigate().refresh();title = webDriver.getTitle();

最后

以上就是这次抓取的全部内容了,虽然只提供了核心代码和抓取思路,但仍希望能够帮助到大家。
对了,如果需要部署项目的话,这部分功能需要部署到windows服务器,使用centos的话无法识别验证码。

记一次批量定时抓取微信公众号文章的实现相关推荐

  1. java 微信文章评论点赞_使用fiddler抓取微信公众号文章的阅读数、点赞数、评论数...

    1 设置fiddler支持https 打开fiddler,在菜单栏中依次选择 [Tools]->[Options]->[HTTPS],勾上如下图的选项: 单击Actions,选择Expor ...

  2. python公众号文章_Python 抓取微信公众号文章

    起因是刷微信的时候看到一篇文章,Python 抓取微信公众号文章保存成pdf,很容易搜到,就不贴出来了 先用chrome登陆微信公众号后台,先获取一下自己的cookie,复制下来就行,解析一下转换成 ...

  3. Python实现抓取微信公众号文章

    本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章. 前言 对于抓取微信公众号文章主要通过代理ip抓包进行的操作,总会出现一些问题,以下问题导致无法抓包. ...

  4. 利用搜狗抓取微信公众号文章

    微信一直是一个自己玩的小圈子,前段时间搜狗推出的微信搜索带来了一丝曙光.搜狗搜索推出了内容搜索和公众号搜索两种,利用后者可以抓取微信公众号的最新内容,看了下还是比较及时的. 每个公众号都有一个open ...

  5. 使用fiddler自动化抓取微信公众号文章的点赞与阅读数

    本文章为lonter首创,只发布在csdn平台,严禁转载 这几天接到任务,需要开发一个微信榜单的功能,因此需要采集微信公众号文章的阅读数,点赞数和评论数,榜单内的微信公众号有一百多个,每个月出一次榜单 ...

  6. python爬虫(17)爬出新高度_抓取微信公众号文章(selenium+phantomjs)

    个人博客请访问 http://www.x0100.top 一.思路分析 目前所知晓的能够抓取的方法有: 1.微信APP中微信公众号文章链接的直接抓取(http://mp.weixin.qq.com/s ...

  7. python抓取微信公众号文章及评论(附过程)

    需求:抓取人民网微信公众号的文章和评论 使用工具: fiddler python3 微信pc客户端 破解过程: 首先 使用fiddler对微信pc端抓包,需要配置https证书,另外最好加个filte ...

  8. 【分享】如何用Pytho抓取微信公众号文章(包括阅读数,点赞数)

    本小白的第一篇技术分享博客,啊哈哈!!(石乐志) 真好,直接切入正题吧,目前来讲微信公众号文章主要有以下三种渠道可以获取,对应有三种抓取方式,如下~~ 搜狗微信点击跳入,这算是对咱reptiler最友 ...

  9. python爬虫抓取微信公众号文章(含全文图以及点赞数、在看数、阅读数)

    因工作需要写了一个微信公众号文章的爬虫程序,贴一下分享给需要的朋友. 首先是抓取文章的url链接,在反复研究之后找到的一个最简单的方法,不需要抓包工具.首先需要自己注册一个微信公众号,有微信即可绑定注 ...

最新文章

  1. ubuntu软件安装(个人PC)
  2. RabbitMQ消息队列系列教程(一)认识RabbitMQ
  3. 针对Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1的解决方案
  4. Redis介绍及部署在CentOS7上(一)
  5. 【算法入门漫画】:“排序算法” 大总结
  6. 牛客练习赛10 F-序列查询(莫队+链表)
  7. 前端学习(2715):重读vue电商网站35之在sessionStorage保存左侧菜单栏的激活状态
  8. python3.5.2安装pygame_【闲来无事,py写game】Mac-Python3.5安装pygame 1.9.2 小计
  9. 中科大 计算机网络13 FTP文件传输协议
  10. 计算机网络学习笔记-1.2.2OSI参考模型(1)
  11. linux ora-00119,Linux oracle ORA-00119 和 ORA-00132
  12. Struts2标签库整理【完整】
  13. 渗透测试——CFS三层靶机渗透
  14. 绑定host:windows与模拟器之绑定host集结
  15. [Pandas技巧] 多列值合并成一列
  16. 美股网页表格数据爬虫设计
  17. 最短路 dij floy spfa
  18. Matlab中的poly2trellis函数使用简介
  19. 足不出户买遍全球:亚马逊海外购启动史上最长“海外购物节”
  20. android仿windows phone界面,安卓仿win10桌面Win 10 Launcher

热门文章

  1. Creo建模(持续更新)
  2. EasyExcel实现Excel文件导入导出功能
  3. Acer传奇Go电脑开机自动安装软件卡死怎么重装系统?
  4. 【软考中级】软件设计师学习笔记
  5. 使用 Vue SVG 快速绘制曲线图(带动画)
  6. 1520 - 骑士的金币(coin)
  7. 华为交换机ERROR DOWN解决办法
  8. 我的macbook应用清单
  9. 爬取拉钩Java招聘数据
  10. ScrollBar使用-很全