webmagic入门-菜鸟教程html to markdown

      最近在学习Java爬虫,发现了webmagic轻量级框架,在网上搜索了一些教程,然后自己尝试着写了一个对 菜鸟教程的爬虫,主要功能为把教程内容html转换为markdown文本,方便离线阅读;  
      做这个工具的主要原因是,我们单位的工作环境一般要求断网,菜鸟教程上的教学作为入门一般不错,为了方便离线学习,做了这个应用;现在写了主要为了分享和自己学习总结;  
第一次写博文,不完善的地方请见谅

关于 **WebMagic**,我就不作介绍了,主页传送门 ->  WebMagic
Maven依赖

<dependency>
    <groupId>us.codecraft</groupId>
    <artifactId>webmagic-core</artifactId>
    <version>0.7.1</version>
</dependency>
<dependency>
    <groupId>us.codecraft</groupId>
    <artifactId>webmagic-extension</artifactId>
    <version>0.7.1</version>
</dependency>

中文文档 ->  http://webmagic.io/docs/zh/  


因为用到了lambda表达式,jdk版本要求1.8+,IDE使用IDEA

----
写个介绍真辛苦,下面进入项目

----
项目创建

  • 创建项目,导入jar包(略)

  • 主要内容结构如图  

Controller - 控制器,Main方法入口

MarkdownSavePipeline - 持久化组件-保存为文件

RunoobPageProcessor - 页面解析组件

Service - 服务提供组件,相当于Utils,主要用于包装通用方法

菜鸟教程页面

这里选取的是 Scala教程作为样板

开始上代码

import us.codecraft.webmagic.Spider;

/**
 * 爬虫控制器,main方法入口
 * Created by bekey on 2017/6/6.
 */
public class Controller {
    public static void main(String[] args) {
//        String url = "http://www.runoob.com/regexp/regexp-tutorial.html";
        String url = "http://www.runoob.com/scala/scala-tutorial.html";
        //爬虫控制器   添加页面解析                添加url(request)     添加持久化组件               创建线程   执行
        Spider.create(new RunoobPageProcessor()).addUrl(url).addPipeline(new MarkdownSavePipeline()).thread(1).run();
    }
}

WebMagic 中主要有四大组件  

  • Downloader 负责下载页面
  • PageProcessor 负责解析页面
  • Scheduler 调度URL
  • Pipeline 持久化到文件/数据库等

一般Downloader和Scheduler不需要定制

 流程核心控制引擎 -- Spider ,用来自由配置爬虫,创建/启动/停止/多线程等

 

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Html;


/**
 * 菜鸟教程markdown转换
 * Created by bekey on 2017/6/6.
 */
public class RunoobPageProcessor implements PageProcessor{
    private static String name = null;
    private static String regex = null;

    // 抓取网站的相关配置,包括编码、重试次数、抓取间隔、超时时间、请求消息头、UA信息等
    private Site site= Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(3000).addHeader("Accept-Encoding", "/")
            .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36");

    @Override
    public Site getSite() {
        return site;
    }

    @Override
    //此处为处理函数
    public void process(Page page) {
        Html html = page.getHtml();
//        String name = page.getUrl().toString().substring();
        if(name == null ||regex == null){
            String url = page.getRequest().getUrl();
            name = url.substring(url.lastIndexOf('/',url.lastIndexOf('/')-1)+1,url.lastIndexOf('/'));
            regex = "http://www.runoob.com/"+name+"/.*";
        }
        //添加访问
        page.addTargetRequests(html.links().regex(regex).all());
        //获取文章主内容
        Document doc = html.getDocument();
        Element article = doc.getElementById("content");
        //获取markdown文本
        String document = Service.markdown(article);
        //处理保存操作
        String fileName = article.getElementsByTag("h1").get(0).text().replace("/","").replace("\\","") + ".md";
        page.putField("fileName",fileName);
        page.putField("content",document);
        page.putField("dir",name);
    }
}

一般爬虫最重要的就是解析,所以必须创建解析器实现PageProcessor接口,

PageProcessor接口有两个方法

  • public Site getSite()   Site 抓取网站的配置,一般可以设为静态属性
  • public void process(Page page) 页面处理函数 , 其中Page 代表了从Downloader下载到的一个页面——可能是HTML,也可能是JSON或者其他文本格式的内容。

属性设置有很多,可以自己尝试,当然抓取间隔不要太短,否则会给目标网站带来很大负担,特别注意

addHeader -- 添加消息头;最基本的反反爬虫手段; 

        Html html = page.getHtml();
//        String name = page.getUrl().toString().substring();
        if(name == null ||regex == null){
            String url = page.getRequest().getUrl();
            name = url.substring(url.lastIndexOf('/',url.lastIndexOf('/')-1)+1,url.lastIndexOf('/'));
            regex = "http://www.runoob.com/"+name+"/.*";
        }
        //添加访问
        page.addTargetRequests(html.links().regex(regex).all());

这段,主要是链接处理;在Controller中,Spider一般有一个入口request,但是不是每发送一个请求就要创建一个Spider(否则要多线程干什么囧);

通过page.addTargetRequests 及其他重载方法可以很轻松地添加请求,请求会放进Scheduler并去重,根据Sleeptime间隔时间访问

links() 方法是Selectable接口的抽象方法,可以提取页面上的链接,因为是要爬取整个教程,所以用正则提取正确的链接,放入Scheduler;

Selectable 相关的抽取元素链式API是WebMagic的一个核心功能。使用Selectable接口,可以直接完成页面元素的链式抽取,也无需去关心抽取的细节。 主要提供 xpath(Xpath选择器) / $(css选择器) / regex(正则抽取) /replace(替换)/links(获取链接) 等方法,不过我不太会用,所以后面页面解析主要还是使用 Jsoup实现

WebMagic PageProcessor 中解析页面主要就是使用Jsoup实现的,Jsoup是一款优秀的页面解析器,具体使用请看官方文档  http://www.open-open.com/jsoup/

        //获取文章主内容
        Document doc = html.getDocument();
        Element article = doc.getElementById("content");

page 和 jsoup的转换  通过getDocument实现,这里的Document类,import org.jsoup.nodes.Document

通过页面结构,我们可以很轻易地发现,教程主要内容都藏在id为content的div里,拿出来

        //获取markdown文本
        String document = Service.markdown(article);

通过静态方法拿到markdown文本,看一下具体实现,Service类

    /**
     * 公有方法,将body解析为markdown文本
     * @param article #content内容
     * @return markdown文本
     */
    public static String markdown(Element article){
        StringBuilder markdown = new StringBuilder("");
        article.children().forEach(it ->parseEle(markdown, it, 0));
        return markdown.toString();
    }

    /**
     * 私有方法,解析单个元素并向StringBuilder添加
     */
    private static void parseEle(StringBuilder markdown,Element ele,int level){
        //处理相对地址为绝对地址
        ele.getElementsByTag("a").forEach(it -> it.attr("href",it.absUrl("href")));
        ele.getElementsByTag("img").forEach(it -> it.attr("src",it.absUrl("src")));
        //先判断class,再判定nodeName
        String className = ele.className();
        if(className.contains("example_code")){
            String code = ele.html().replace("&nbsp;"," ").replace("<br>","");
            markdown.append("```\n").append(code).append("\n```\n");
            return;
        }
        String nodeName = ele.nodeName();
        //获取到每个nodes,根据class和标签进行分类处理,转化为markdown文档
        if(nodeName.startsWith("h") && !nodeName.equals("hr")){
            int repeat = Integer.parseInt(nodeName.substring(1)) + level;
            markdown.append(repeat("#", repeat)).append(' ').append(ele.text());
        }else if(nodeName.equals("p")){
            markdown.append(ele.html()).append("  ");
        }else if(nodeName.equals("div")){
            ele.children().forEach(it -> parseEle(markdown, it, level + 1));
        }else if(nodeName.equals("img")) {
            ele.removeAttr("class").removeAttr("alt");
            markdown.append(ele.toString()).append("  ");
        }else if(nodeName.equals("pre")){
            markdown.append("```").append("\n").append(ele.html()).append("\n```");
        }else if(nodeName.equals("ul")) {
            markdown.append("\n");
            ele.children().forEach(it -> parseEle(markdown, it, level + 1));
        }else if(nodeName.equals("li")) {
            markdown.append("* ").append(ele.html());
        }
        markdown.append("\n");
    }

    private static String repeat(String chars,int repeat){
        String a = "";
        if(repeat > 6) repeat = 6;
        for(int i = 0;i<=repeat;i++){
            a += chars;
        }
        return a;
    }

不得不说,java8的lambda表达式太好使了,让java竟然有了脚本的感觉(虽然其他很多语言已经实现很久了)

这里是具体的业务实现,没有什么好特别讲解的,就是根据规则一点点做苦力;我这里主要依靠class 和 nodeName 把html转为markdown,处理得不算很完善吧,具体实现可以慢慢改进~

需要注意的是,这里的Element对象,都是来自于Jsoup框架,使用起来很有JavaScript的感觉,如果你常使用js,对这些方法名应该都挺了解的,就不详细讲了;如果Element里属性有连接,通过absUrl(String attrName)可以很方便得获得绝对链接地址;

回到process函数

        //处理保存操作
        String fileName = article.getElementsByTag("h1").get(0).text().replace("/","").replace("\\","") + ".md";
        page.putField("fileName",fileName);
        page.putField("content",document);
        page.putField("dir",name);

再得到文本后,我们就可以对文本进行持久化处理;事实上,我们可以不借助Pieline组件进行持久化,但是基于模块分离,以及更好的复用/扩展,实现一个持久化组件也是有必要的(假如你不仅仅需要一个爬虫)

这里,page.putField 方法,实际上是讲内容放入一个 ResultItems 的Map组件中,它负责保存PageProcessor处理的结果,供Pipeline使用. 它的API与Map很类似,但包装了其他一些有用的信息,值得注意的是它有一个字段,skip,page中可以通过page.setSkip(true)方法,使得页面不必持久化

/**
 * 保存文件功能
 * Created by bekey on 2017/6/6.
 */
public class MarkdownSavePipeline implements Pipeline {
    @Override
    public void process(ResultItems resultItems, Task task) {
        try {
            String fileName = resultItems.get("fileName");
            String document = resultItems.get("content");
            String dir = resultItems.get("dir");
            Service.saveFile(document,fileName,dir);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

Pipeline接口,同样要实现一个  

public void process(ResultItems resultItems, Task task) 方法,处理持久化操作

ResultItems 已经介绍过了,里面除了有你page中保存的内容外,还提供了getRequest()方法,获取本次操作的Request对象,和一个getAll()的封装方法,给你迭代;

Task对象提供了两个方法

  • getSite()
  • getUUID()

没有使用过,但是看方法名大概能知道是做什么的;

Serivice.saveFile 是我自己简单封装的保存文件方法,在src同级目录创建以教程命名的文件夹,以每个页面标题为文件名创建.md文件.简单的IO操作,就不贴出来;

特别注意的是WebMagic框架会在底层catch异常,但是却不会报错,所以开发调试的时候,如果要捕获异常的话,需要自己try catch ,特别是那些RuntimeException

 

啰啰嗦嗦打了好多,完整代码下载,我的GitHub

https://github.com/BekeyChao/HelloWorld/tree/master/src

因为没有用git管理(主要有一些其他内容),所以是手动同步的,如果运行不起来,就好好研究吧~

转载于:https://my.oschina.net/u/3491123/blog/917836

weixin_33713503
关注 关注
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
视频教程-Java爬虫入门到精通-Java
weixin_27219125的博客
05-28 482
Java爬虫入门到精通 十年项目开发经验,主要从事java相关的开发,熟悉...
webmagic中文教程(在线教程word版)
01-12
java爬虫webmagic的word版教程最新版(2016-1-12),来自其中文网站:http://webmagic.io/docs/zh
用php将markdownhtml代码_HTML to Markdown - 用PHP将HTMLMarkdown.
weixin_39831039的博客
03-09 265
HTML To Markdown for PHP Library which converts HTML to Markdown for your sanity and convenience.Requires: PHP 5.3+Lead Developer: @colinodellOriginal Author: @nickcernisWhy convert HTML to Mark...
webmagic总体介绍
大数据训练营
12-03 1万+
1.WebMagic概览 WebMagic项目代码分为核心和扩展两部分。核心部分(webmagic-core)是一个精简的、模块化的爬虫实现,而扩展部分则包括一些便利的、实用性的功能。WebMagic的架构设计参照了Scrapy,目标是尽量的模块化,并体现爬虫的功能特点。 这部分提供非常简单、灵活的API,在基本不改变开发模式的情况下,编写一个爬虫。 扩展部分(webmagic-extens
Java爬虫框架——WebMagic入门
weixin_41532316的博客
08-27 474
一:webMagic介绍 利用HttpClient与Jsoup可以帮助我们完简单的或者规模较小的爬虫案例,但是他俩支撑不起企业级爬虫的开发。今天笔者整理了一款船新版本的爬虫框架——WebMagic,它的底层是由HttpClient与Jsoup结合实现的,它可以帮助我们更加方便快捷的开发爬虫WebMagic的设计目标是开发模块化。它分为核心和扩展两部分。核心部分是精简模块化的爬虫实现,而扩...
WebMagic快速入门
weixin_45829957的博客
01-09 3969
一、WebMagic介绍 WebMagic的结构分为Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由Spider将它们彼此组织起来。这四大组件对应爬虫生命周期中的下载、处理、管理和持久化等功能。WebMagic的设计参考了Scapy,但是实现方式更Java化一些。 而Spider则将这几个组件组织起来,让它们可以互相交互,流程化的执行,可以认为Spider是一个大的容器,它也是WebMagic逻辑的核心。 1.1 WebMagic的四个组件 1
markdown-it-charts:markdown-it图表插件
05-13
markdown-it的图表插件。 快速轻松地扩展markdown-it。 支持chart.js,echarts,highcharts,CHARTIST,c3.js,tauCharts。 安装 node.js和Bower: npm install markdown-it-charts --save bower install markdown-...
markdown-it-vue:markdown-it的vue库
02-04
markdown-it的Vue库。 在线演示 安装 npm install markdown-it-vue 支持 图像大小和查看器 官方降价语法。 GFM目录 GFM风格 表情符号 仅简单 Flowcharts.js 下标/上标 信息| 错误警告信息提示 插件清单 降价 ...
markdown-it-html5-media:极简主义者markdown-it插件,使用图像语法
05-06
markdown-it-html5-media 使用图像语法将markdown-it的<video> / <audio>插件最小化。 受启发。 主要区别: 仅支持图像语法: ![descriptive text](video.mp4) ,这是CommonMark人们的语法 将视频和...
broccoli-jsdoc-to-markdown
06-15
用于 jsdoc-to-markdown 的西兰花插件安装$ npm install --save broccoli-jsdoc-to-markdown用法JavaScript var broccoli - jsdoc - to - markdown = require ( 'broccoli-jsdoc-to-markdown' ) ;broccoli - jsdoc -...
markdown-it-table:markdown-it markdown解析器插件,添加具有嵌套块语法支持的表
04-27
$ yarn add markdown-it-table 用 在里面 var md = require ( 'markdown-it' ) ( ) ; var { markdownItTable } = require ( 'markdown-it-table' ) ; md . use ( markdownItTable [ , options ] ) ;
webmagic (项目+全部jar包+教程文档)
04-01
webmagic (项目+全部jar包+教程文档)版本是当前最新webmagic-0.7.3。可以参考博文:https://blog.csdn.net/qq_29914837/article/details/88918685
网络爬虫——WebMagic详解(一)
吴声子夜歌的博客
07-24 2282
Downloader、PageProcessor、Scheduler、Pipeline都是Spider的一个属性,这些属性是可以自由设置的,通过设置这个属性可以实现不同的功能。核心部分(webmagic-core)是一个精简的、模块化的爬虫实现,而扩展部分则包括一些便利的、实用性的功能。第一部分关于爬虫的配置,包括编码、抓取间隔、超时时间、重试次数等,也包括一些模拟的参数,例如User Agent、cookie,以及代理的设置,我们会在第4部分-“爬虫的配置”里进行介绍。爬虫的监控是0.5.0新增的功能。
在线HTMLMarkDown工具
Linux,Java,SpringBoot,Python,Lua略知一点
03-31 1727
在线HTMLMarkDown工具 在线HTMLMarkDown工具 Markdown是一种轻量级标记语言,创始人为约翰·格鲁伯(英语:John Gruber)。 它允许人们使用易读易写的纯文本格式编写文档,然后转换有效的XHTML(或者HTML)文档。 Markdown是一种轻量级标记语言,创始人为约翰·格鲁伯(英语:John Gruber)。 它允许人们使用易读易写的纯文本格式编写文档,然后转换有效的XHTML(或者HTML)文档。 https://tooltt.com/html2mar
WebMagic简明教程(一)
chenxiaokang的博客
07-23 8306
WebMagic简明教程(一)前言做项目需要爬取一些数据,不想用Python,就尝试了下webmagic这个爬虫框架,总的来说上手还是比较简单的,这里来总结一下.webmagic是一个简单灵活的Java爬虫框架,如果你熟悉Java而且不想用Python写爬虫,那么webmagic是一个不错的选择.实战日常前戏 首先呢,咱们来先把jar包下载下来:https://github.com/code4cra
WebMagic入门——框架的基本了解
weixin_44018051的博客
12-21 264
该文章仅用于自己学习整理,大部分内容来自转载 maven配置 <dependency> <groupId>us.codecraft</groupId> <artifactId>webmagic-core</artifactId> <version>0.7.3</version> </dependency> <dependency> <groupId>us.c
Java爬虫案例 -- springboot 整合 webmagic 爬取爱站网百度权重数据(保姆级教程)
ThinkingOverflow的博客
08-15 988
本文以爬取 爱站网百度权重(https://baidurank.aizhan.com/) 为例子,详细介绍了用 Java 爬虫框架 webmagic 爬取网站数据的方法。
WebMagic爬虫入门教程(一)简介
大漠帝国的博客
10-30 1万+
(一)前言 工作学习中,需要进行爬虫。百度百科上说,网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。 网络爬虫,我是这样理解的,简单说,就是下载web网页上的html代码中的信息。 那么到底用什么语言...
WebMagic-使用入门
热门推荐
一个有趣、有料、有内涵的地方!
12-15 3万+
原文出自:http://webmagic.io/docs/zh 访问经常出错,于是把文档转到自己博客里 1基本的爬虫WebMagic里,实现一个基本的爬虫只需要编写一个类,实现PageProcessor接口即可。这个类基本上包含了抓取一个网站,你需要写的所有代码。 同时这部分还会介绍如何使用WebMagic的抽取API,以及最常见的抓取结果保存的问题。 1.1 实现PagePr
npm install --save github-markdown-css/github-markdown.css
最新发布
09-06
npm install --save github-markdown-css/github-markdown.css 是一条命令,用于在使用npm包管理器的项目中安装名为 github-markdown-css 的包,并将其保存为依赖。该包提供了 GitHub 风格的 Markdown 样式表,可以...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 最近沉迷美女图片无法自拔,所以我决定用PHP扒海量妹子图 91427
  • tomcat部署war包访问显示404 28976
  • 关于ModuleNotFoundError: No module named 'urllib3'解决 26874
  • a padding to disable MSIE and Chrome friendly error page 填充禁用MSIE铬友好的错误页面 25947
  • elementui的loading啊。。。踩坑了。。。 25547

最新评论

  • 交换机***查询篇

    菜鸡小闫: 请问老师,vidl-89%是什么啊,咋这么高

  • tomcat部署war包访问显示404

    майр: 解决了吗?表情包

  • Pycharm: 代码跳转如何回退 (小技巧)

    JLA: 快捷键:Ctrl+Alt+键盘的左/右

  • tomcat部署war包访问显示404

    乱我道心: 解决了吗?

  • tomcat部署war包访问显示404

    丶清杉: 帮我解决了问题,原来是未配置的原因,之前找的部署流程博客少了这一步。一看到是配置,恍然大悟之感,感谢您啦~

大家在看

  • 【算法】JZ30 包含min函数的栈 109
  • 算法思想总结:字符串 1605
  • IDEA中创建一个SpringBoot项目并提交到git仓库(日常开发-保姆级手把手超详细截图)
  • AIGC高频产品面试题(专有名词科普及其在AI领域中的应用)
  • SSH服务与免密登录 546

最新文章

  • 构建安全的数据访问-异常管理(八)
  • 最简单的限制edit输入
  • ProtocolException : 已超过传入消息(65536)的最大消息大小配额。
2019年402篇
2018年709篇
2017年976篇
2016年551篇
2015年428篇
2014年312篇
2013年287篇
2012年260篇
2011年211篇
2010年134篇
2009年128篇
2008年82篇
2007年65篇
2006年39篇
2005年21篇
2004年10篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

PHP网站源码大浪网站优化龙华关键词按天扣费双龙阿里店铺运营布吉seo优化坪地百度竞价吉祥百度网站优化排名大运优秀网站设计塘坑seo南澳百度seo荷坳seo排名东莞百度seo观澜企业网站改版吉祥网站制作设计荷坳网站优化软件平湖网站优化排名丹竹头英文网站建设大浪百度爱采购龙华百度标王南山网络推广盐田企业网站制作光明百度关键词包年推广布吉优化惠州网站推广系统宝安优化松岗百度竞价包年推广宝安营销网站大鹏网络广告推广布吉网站开发罗湖SEO按天收费坪地企业网站建设歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

PHP网站源码 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化