zoukankan      html  css  js  c++  java
  • 腾讯新闻评论数据爬取

     

    前言

    鉴于最近在做观点挖掘的相关工作,观点的数据源是网络评论数据,于是第一个想到的就是新闻观点数据,一个热门的新闻可能一晚上就会有上万条评论,所以如何分析并利用好这些评论信息,将会是一件非常有意思的事情,观点挖掘是我研究的目的,当然要想很好解决这个问题,所以我自然要解决数据源的问题,于是乎,我就想到了去爬取腾讯新闻的评论数据。下面我会介绍一下这个过程,这个过程还是非常有意思的哦。

    为什么爬的是腾讯新闻的数据

    我从网上查阅了许多爬取新闻数据的相关技术帖,发现除了腾讯的之外,还有新浪,网易的比较多,但是他们的请求链接都不是那么好破解,腾讯新闻的稍稍简单一点,而且初步分析了一下,可以利用技术的手段去构造请求,从而获取评论数据。先来看一个例子链接,这个也是我从网上找的。

    http://coral.qq.com/article/1004703995/comment?commentid=0&reqnum=20&tag=&callback=mainComment&_=1389623278900

    链接附带的参数还是有点多的,下面给出参数的各个意思:

    http://coral.qq.com/article/评论页ID(即cmt_id)/comment?commentid=起始ID&reqnum=显示数目&tag=&callback=mainComment&_=时间戳+3位随机整数

    最后一位随机值其实没什么用处了。然后点击链接,我们截取其中的一条评论数据,获取到的数据是这样的:

    mainComment({"errCode":0,"data":{"targetid":1004703995,"display":1,"total":14000,"reqnum":20,"retnum":20,"maxid":"5990116449200978034","first":"5990116449200978034","last":"5840477226068943893","hasnext":true,"commentid":[{"id":"5990116449200978034","rootid":"0","targetid":1004703995,"parent":"0","timeDifference":"04u670804u65e5 21:44:12","time":1428155052,"content":"u65e9u8be5u7528u56fdu4ea7u7684u8f66u4e86uff0cu7279u522bu662fu7ea2u65d7u8001u724cu5b50uff0cu6240u6709u7684u516cu8f66u5e94u8be5u90fdu7528u56fdu4ea7u7684uff0cu4f60u770bu97e9u56fdu4ebau6240u6709u7528u7684u90fdu4ee5u56fdu4ea7u4e3au4e3b","title":"","up":"0","rep":"0","type":"1","hotscale":"0","checktype":"1","checkstatus":"1","isdeleted":"0","tagself":"","taghost":"","source":"2","location":"","address":"","rank":"-1","custom":"","extend":{"at":0,"ut":0},"orireplynum":"0","richtype":0,"userid":"171498810","poke":0,"abstract":"","replyuser":"","replyuserid":0,"replyhwvip":0,"replyhwlevel":0,"userinfo":{"userid":"171498810","uidex":"eca292c6a6414f6e1fcb977697686602af","nick":"HLXu6d77u5170u8f69","head":"http://q1.qlogo.cn/g?b=qq&k=IFD4IB50ib9kwDdYwdo4Rxw&s=40&t=1431792000","gender":1,"viptype":"0","mediaid":0,"region":"u4e2du56fd:u5c71u4e1c:u4e1cu8425","thirdlogin":0,"hwvip":0,"hwlevel":0,"identity":"","wbuserinfo":{"name":"zhangzhongliang4372","nick":"u5f20u5fe0u826f","url":"","vip":0,"ep":0,"brief":"","identification":"","intro":"","liveaddr":{"country":"1","province":"37","city":"5","area":""},"gender":1,"level":0,"classify":""},"remark":"","fnd":0}},

    一个超级庞大的json字符串,而且评论数据content里面的中文被编成Unicode的格式了,无法直接查看,在评论数据中,有时还会有用户的许多信息。这样不直观,可以在Google上去查看,但是得需要安装jsonView插件,会有一定的结构呈现:

    接下来我们要好好的分析一下这里面的数据属性结构了。

    腾讯新闻评论数据构成

    我们关注的属性值不会很多,首先这些数据是被mainComment这个包着的,所以在解析之前需要把这个得剥离掉。

    1、errCode:首先有errCode,一看就知道是响应回复值,用来判断请求是否成功和失败了。

    2.、targetId:然后data才是我们所关心的,首先是一个targetId,暂且可先理解为具体新闻的id,但是事实上不是,这个在后面会做解释

    3、total:指的是的此条新闻的所有评论数据的总条数。

    4、reqnum:此次请求评论数据的条数。这里需要小小提醒一下,每次请求数据的上限条数50条,如果某次请求超出这个值,还是会返回50条。

    5、retnum:此次请求返回的评论数,如果没有到评论数据的末尾,一般请求值与返回值是相等的。

    6、maxid:指的是此次返回的评论数据中评论id最大的值。

    7、firsr:指的是返回的评论中的首条评论id。

    8、last:指的是返回的评论数据中的末尾条的评论id。

    然后这个时候可以在介绍一下刚刚提到的问题,targetid其实不是真实的新闻页id,其实是一个映射的关系吧,一个新闻页会对应一个评论id,这个id其实是一个类似于评论组id的概念,然后在这个id下面,每条评论数据都有自己的id值,所以才会有first,last这些值的存在。

    下面再简单一看下评论数据的属性信息了

    1、id:针对自己的评论id,这个id是唯一的,至于具体怎么生出,这个我也不清楚。

    2、targetid:同样有定义targetid的定义,表明所属于哪条新闻的评论数据。

    3、time:评论数据的发表时间,以时间戳的方式存在。

    4、content:这个就是我们最最关注的评论数据了。

    如何爬取新闻评论数据

    在了解了评论数据的结构数据后,我们当然想要的是如何去获取其中的数据,请求模板链接已经在上面给出了,再次在下面给出,

    http://coral.qq.com/article/评论页ID(即cmt_id)/comment?commentid=起始ID&reqnum=显示数目&tag=&callback=mainComment&_=时间戳+3位随机整数

    需要填入的参数有,reqnum,每次请求数,评论页id,其实id,时间戳那个你可以固定写死都没问题。OK,下面我们一个个解决。

    1、评论页id,即cmt_id,这个没有什么API,只能自己去匹配,爬取,常用的办法就是解析新闻页的HTML代码,利用写好的正则表达式去匹配。cmt_id在详情页的代码中的展示为

    所以可以写一个cmt_id = "(,*)";的匹配规则去匹配。在我后面的代码实现中都会出现。匹配到cmt_id后,就第一个参数搞定。

    2、起始id,指的是从哪个id开始的评论数据,因为每次获取的都是一批数据,要知道起始位置才能获取相对应的数据,开始时0,表明取得是最前面的几十条数据,如果想要接下来取的话,需要把这批数据中最后一个评论id,加入到新的请求中,才能往后取,就是刚刚的last值的定义。

    3‘、reqnum请求数据这个很简单,不超过50都没问题。

    以上具体的过程会在我后面的程序中有所体现,现在不理解没有关系。

    爬取示例

    我选取了一则最近的新闻,页面如下

    标题为俄罗斯红场阅兵....ok,标题其实我们也可以爬到的。查看一下目前最新的一部分评论,用于后面做对比:

    然后我们爬取一下数据,输出到本地的一个文件中,格式为发表时间戳+评论内容。

    然后与网上的数据比对一下

    数据完全吻合,由此评论过程顺利完成。而且能够连续的爬取到数据。下面看看关键的代码实现

    爬取算法代码实现

    只需要输入新闻页的链接即可。在算法中会有2次的http请求,第一次获取cmt_id评论id,第二次才是评论数据的爬取。废话不多说,贴代码,这里小小提醒一下,为了避免太频繁的爬取请求,我在每次爬取完毕之后进行随机几秒的时间睡眠。在解析json数据时,需要有Gson的依赖,在我的github上完整的代码和jar包,上面还有如何使用,地址同样贴上,点击我的腾讯新闻评论数据爬取项目

    爬取工具封装类QQNewCrawler.java:

    1. package TextMining.crawler;  
    2.   
    3. import java.io.BufferedReader;  
    4. import java.io.File;  
    5. import java.io.FileNotFoundException;  
    6. import java.io.FileOutputStream;  
    7. import java.io.FileReader;  
    8. import java.io.IOException;  
    9. import java.io.InputStreamReader;  
    10. import java.io.PrintStream;  
    11. import java.net.URL;  
    12. import java.net.URLConnection;  
    13. import java.text.MessageFormat;  
    14. import java.util.ArrayList;  
    15. import java.util.Random;  
    16. import java.util.regex.Matcher;  
    17. import java.util.regex.Pattern;  
    18.   
    19. import TextMining.crawler.entity.Comment;  
    20. import TextMining.crawler.entity.Data;  
    21. import TextMining.crawler.entity.DataContainer;  
    22.   
    23. import com.google.gson.Gson;  
    24.   
    25. /** 
    26.  * 腾讯新闻爬虫工具类 
    27.  *  
    28.  *
    29.  *  
    30.  */  
    31. public class QQNewsCrawler {  
    32.     // 腾讯新闻评论链接url的格式  
    33.     public static final String NEWS_COMMENTS_URL_FORMAT = "http://coral.qq.com/article/{0}/comment?commentid={1}&reqnum={2}&tag=&callback=mainComment&_=1389623278900";  
    34.   
    35.     // 腾讯新闻详情页的链接  
    36.     private String newsUrl;  
    37.     //爬取到的新闻标题  
    38.     private String newsTitle;  
    39.     //评论数据输出路径  
    40.     private String outputPath;  
    41.     // 需要爬取的评论数总量  
    42.     private int totalCommentcount;  
    43.     // 每次请求的评论数,一次上限50条评论  
    44.     private int reqCommentNum;  
    45.     // 评论列表  
    46.     private ArrayList<Comment> commentLists;  
    47.   
    48.     public QQNewsCrawler(String newUrl, int totalCommentcount, int reqCommentNum, String outputPath) {  
    49.         this.newsUrl = newUrl;  
    50.         this.totalCommentcount = totalCommentcount;  
    51.         this.outputPath = outputPath;  
    52.           
    53.         if (reqCommentNum > 50) {  
    54.             // 每次请求最多只能50条  
    55.             reqCommentNum = 50;  
    56.         }  
    57.         this.reqCommentNum = reqCommentNum;  
    58.     }  
    59.   
    60.     /** 
    61.      * 获取评论内容数据 
    62.      * @return 
    63.      */  
    64.     public ArrayList<Comment> getCommentLists() {  
    65.         return commentLists;  
    66.     }  
    67.       
    68.     /** 
    69.      * 获取新闻标题 
    70.      * @return 
    71.      */  
    72.     public String getNewsTitle(){  
    73.         return this.newsTitle;  
    74.     }  
    75.   
    76.     /** 
    77.      * 从新闻详情页中爬取新闻标题和评论ID 
    78.      *  
    79.      * @return 
    80.      */  
    81.     public String[] crawlCmtIdAndTitle() {  
    82.         String[] array;  
    83.         String[] tempArray;  
    84.         // 页面HTML字符  
    85.         String htmlStr;  
    86.         String cmtId;  
    87.         String newsTitle;  
    88.         String filePath = "C:\Users\hadoop\Desktop\input\input2.txt";  
    89.         Pattern p;  
    90.         Matcher m;  
    91.   
    92.         cmtId = null;  
    93.         newsTitle = null;  
    94.         array = new String[2];  
    95.         htmlStr = sendGet(newsUrl);  
    96.         // htmlStr = readDataFile(filePath);  
    97.   
    98.         p = Pattern.compile("cmt_id = (.*);");  
    99.         m = p.matcher(htmlStr);  
    100.   
    101.         while (m.find()) {  
    102.             cmtId = m.group();  
    103.             System.out.println(cmtId);  
    104.             break;  
    105.         }  
    106.   
    107.         p = Pattern.compile("<title>(.*)</title>");  
    108.         m = p.matcher(htmlStr);  
    109.   
    110.         while (m.find()) {  
    111.             newsTitle = m.group();  
    112.             System.out.println(newsTitle);  
    113.             break;  
    114.         }  
    115.   
    116.         // 对匹配到的评论id字符做解析  
    117.         if (cmtId != null && !cmtId.equals("")) {  
    118.             tempArray = cmtId.split(";");  
    119.             cmtId = tempArray[0];  
    120.             tempArray = cmtId.split("=");  
    121.             cmtId = tempArray[1].trim();  
    122.             System.out.println(cmtId);  
    123.         }  
    124.   
    125.         int pos1;  
    126.         int pos2;  
    127.         // 对匹配到的新闻标题做解析  
    128.         if (newsTitle != null && !newsTitle.equals("")) {  
    129.             pos1 = newsTitle.indexOf(">");  
    130.             pos2 = newsTitle.lastIndexOf("<");  
    131.   
    132.             newsTitle = newsTitle.substring(pos1 + 1, pos2);  
    133.             System.out.println(newsTitle);  
    134.         }  
    135.   
    136.         array[0] = cmtId;  
    137.         array[1] = newsTitle;  
    138.         this.newsTitle = newsTitle;  
    139.           
    140.         return array;  
    141.     }  
    142.   
    143.     /** 
    144.      * 根据新闻评论ID爬取腾讯新闻评论数据 
    145.      *  
    146.      * @throws 
    147.      */  
    148.     public void crawlNewsComments() {  
    149.         String resultCommentStr;  
    150.         String requestUrl;  
    151.         String cmtId;  
    152.         String[] info;  
    153.         String startCommentId;  
    154.         int index1;  
    155.         int index2;  
    156.         // 当前获取到评论条数  
    157.         int currentCommentNum;  
    158.         int sleepTime;  
    159.         Random random;  
    160.   
    161.         startCommentId = "";  
    162.         currentCommentNum = 0;  
    163.         random = new Random();  
    164.         commentLists = new ArrayList<>();  
    165.   
    166.         info = crawlCmtIdAndTitle();  
    167.         cmtId = info[0];  
    168.         // cmtId = "1004703995";  
    169.   
    170.         // 当请求总量达到要求的量时,跳出循环  
    171.         while (currentCommentNum < totalCommentcount) {  
    172.             requestUrl = MessageFormat.format(NEWS_COMMENTS_URL_FORMAT, cmtId,  
    173.                     startCommentId, reqCommentNum);  
    174.             resultCommentStr = sendGet(requestUrl);  
    175.   
    176.             // 截取出json格式的评论数据  
    177.             index1 = resultCommentStr.indexOf("{");  
    178.             index2 = resultCommentStr.lastIndexOf("}");  
    179.             resultCommentStr = resultCommentStr.substring(index1, index2 + 1);  
    180.   
    181.             System.out.println(resultCommentStr);  
    182.             // 以上次最后一条评论的id为起始ID,继续爬取数据  
    183.             startCommentId = parseJSONData(resultCommentStr);  
    184.   
    185.             // 如果解析出现异常,则立即退出  
    186.             if (startCommentId == null) {  
    187.                 break;  
    188.             }  
    189.   
    190.             try {  
    191.                 // 随机睡眠1到5秒  
    192.                 sleepTime = random.nextInt(5) + 1;  
    193.                 Thread.sleep(1000 * sleepTime);  
    194.             } catch (InterruptedException e) {  
    195.                 // TODO Auto-generated catch block  
    196.                 e.printStackTrace();  
    197.             }  
    198.   
    199.             currentCommentNum += reqCommentNum;  
    200.         }  
    201.   
    202.         // 最后将本次爬取的所有评论写入到文件中  
    203.         writeStringToFile(commentLists, outputPath);  
    204.     }  
    205.   
    206.     /** 
    207.      * 解析评论数据的json格式字符串 
    208.      *  
    209.      * @param dataStr 
    210.      *            json数据 
    211.      * @return 返回此次获取的最后一条评论的id 
    212.      */  
    213.     private String parseJSONData(String dataStr) {  
    214.         String lastId;  
    215.         Gson gson = new Gson();  
    216.         DataContainer dataContainer;  
    217.         Data data;  
    218.         ArrayList<Comment> cList;  
    219.   
    220.         dataContainer = gson.fromJson(dataStr, DataContainer.class);  
    221.         // 如果获取数据异常,则返回控制  
    222.         if (dataContainer == null || dataContainer.getErrCode() != 0) {  
    223.             return null;  
    224.         }  
    225.   
    226.         data = dataContainer.getData();  
    227.         //一旦发现已经没有数据了,则返回  
    228.         if (data == null) {  
    229.             return null;  
    230.         }  
    231.   
    232.         cList = data.getCommentid();  
    233.         if(cList == null || cList.size() == 0){  
    234.             return null;  
    235.         }  
    236.         commentLists.addAll(cList);  
    237.   
    238.         lastId = dataContainer.getData().getLast();  
    239.   
    240.         return lastId;  
    241.     }  
    242.   
    243.     /** 
    244.      * 向指定URL发送GET方法的请求 
    245.      *  
    246.      * @param url 
    247.      *            发送请求的URL 
    248.      * @return URL 所代表远程资源的响应结果 
    249.      */  
    250.     private String sendGet(String requestUrl) {  
    251.         String result = "";  
    252.         BufferedReader in = null;  
    253.         try {  
    254.             URL realUrl = new URL(requestUrl);  
    255.             // 打开和URL之间的连接  
    256.             URLConnection connection = realUrl.openConnection();  
    257.             // 设置通用的请求属性  
    258.             connection.setRequestProperty("accept", "*/*");  
    259.             connection.setRequestProperty("connection", "Keep-Alive");  
    260.             connection.setRequestProperty("user-agent",  
    261.                     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");  
    262.             // 建立实际的连接  
    263.             connection.connect();  
    264.   
    265.             // 定义 BufferedReader输入流来读取URL的响应  
    266.             in = new BufferedReader(new InputStreamReader(  
    267.                     connection.getInputStream()));  
    268.             String line;  
    269.             while ((line = in.readLine()) != null) {  
    270.                 result += line;  
    271.             }  
    272.         } catch (Exception e) {  
    273.             System.out.println("发送GET请求出现异常!" + e);  
    274.             e.printStackTrace();  
    275.         }  
    276.         // 使用finally块来关闭输入流  
    277.         finally {  
    278.             try {  
    279.                 if (in != null) {  
    280.                     in.close();  
    281.                 }  
    282.             } catch (Exception e2) {  
    283.                 e2.printStackTrace();  
    284.             }  
    285.         }  
    286.         return result;  
    287.     }  
    288.   
    289.     /**  
    290.      * 从文件中读取数据  
    291.      */  
    292.     private String readDataFile(String filePath) {  
    293.         File file = new File(filePath);  
    294.         String resultStr = "";  
    295.   
    296.         try {  
    297.             BufferedReader in = new BufferedReader(new FileReader(file));  
    298.             String str;  
    299.             while ((str = in.readLine()) != null) {  
    300.                 resultStr = resultStr + str;  
    301.             }  
    302.             in.close();  
    303.         } catch (IOException e) {  
    304.             e.getStackTrace();  
    305.         }  
    306.   
    307.         return resultStr;  
    308.     }  
    309.   
    310.     /** 
    311.      * 写评论到目标文件中 
    312.      *  
    313.      * @param resultStr 
    314.      */  
    315.     public void writeStringToFile(ArrayList<Comment> commentList,  
    316.             String desFilePath) {  
    317.         File file;  
    318.         PrintStream ps;  
    319.   
    320.         try {  
    321.             file = new File(desFilePath);  
    322.             ps = new PrintStream(new FileOutputStream(file));  
    323.   
    324.             for (Comment c : commentList) {  
    325.                 ps.println(c.getTime() + ":" + c.getContent());// 往文件里写入字符串  
    326.             }  
    327.   
    328.             ps.close();  
    329.         } catch (FileNotFoundException e) {  
    330.             // TODO Auto-generated catch block  
    331.             e.printStackTrace();  
    332.         }  
    333.     }  
    334. }  
    三大实体类定义:

    Comment.java:

    1. package TextMining.crawler.entity;  
    2.   
    3. /** 
    4.  * 具体的单条评论类 
    5.  *  
    6.  *  
    7.  */  
    8. public class Comment {  
    9.     // 代表的是此评论的ID  
    10.     private String id;  
    11.     // 评论对应的新闻ID  
    12.     private String targetid;  
    13.     // 评论的时间  
    14.     private long time;  
    15.     // 评论的具体内容  
    16.     private String content;  
    17.     // 评论被顶的次数  
    18.     private String up;  
    19.   
    20.     public String getId() {  
    21.         return id;  
    22.     }  
    23.   
    24.     public void setId(String id) {  
    25.         this.id = id;  
    26.     }  
    27.   
    28.     public String getTargetid() {  
    29.         return targetid;  
    30.     }  
    31.   
    32.     public void setTargetid(String targetid) {  
    33.         this.targetid = targetid;  
    34.     }  
    35.   
    36.     public long getTime() {  
    37.         return time;  
    38.     }  
    39.   
    40.     public void setTime(long time) {  
    41.         this.time = time;  
    42.     }  
    43.   
    44.     public String getContent() {  
    45.         return content;  
    46.     }  
    47.   
    48.     public void setContent(String content) {  
    49.         this.content = content;  
    50.     }  
    51.   
    52.     public String getUp() {  
    53.         return up;  
    54.     }  
    55.   
    56.     public void setUp(String up) {  
    57.         this.up = up;  
    58.     }  
    59.   
    60. }  
    Data.java:
    1. package TextMining.crawler.entity;  
    2.   
    3. import java.util.ArrayList;  
    4.   
    5. /** 
    6.  * 总评论实体 
    7.  *  
    8.  *
    9.  *  
    10.  */  
    11. public class Data {  
    12.     // 对应的新闻ID  
    13.     private String targetid;  
    14.     // 此新闻的评论总数  
    15.     private int total;  
    16.     // 当前获取数据评论中的首条评论子id  
    17.     private String first;  
    18.     // 当前获取数据评论中的末尾评论子id  
    19.     private String last;  
    20.     // 判断在此数据后面还有没有评论数据  
    21.     private boolean hasnext;  
    22.     // 具体子评论列表  
    23.     private ArrayList<Comment> commentid;  
    24.   
    25.     public String getTargetid() {  
    26.         return targetid;  
    27.     }  
    28.   
    29.     public void setTargetid(String targetid) {  
    30.         this.targetid = targetid;  
    31.     }  
    32.   
    33.     public int getTotal() {  
    34.         return total;  
    35.     }  
    36.   
    37.     public void setTotal(int total) {  
    38.         this.total = total;  
    39.     }  
    40.   
    41.     public String getFirst() {  
    42.         return first;  
    43.     }  
    44.   
    45.     public void setFirst(String first) {  
    46.         this.first = first;  
    47.     }  
    48.   
    49.     public String getLast() {  
    50.         return last;  
    51.     }  
    52.   
    53.     public void setLast(String last) {  
    54.         this.last = last;  
    55.     }  
    56.   
    57.     public boolean isHasnext() {  
    58.         return hasnext;  
    59.     }  
    60.   
    61.     public void setHasnext(boolean hasnext) {  
    62.         this.hasnext = hasnext;  
    63.     }  
    64.   
    65.     public ArrayList<Comment> getCommentid() {  
    66.         return commentid;  
    67.     }  
    68.   
    69.     public void setCommentid(ArrayList<Comment> commentid) {  
    70.         this.commentid = commentid;  
    71.     }  
    72. }  
    DataContainer.java:
    1. package TextMining.crawler.entity;  
    2.   
    3. /** 
    4.  * 数据外层包装类 
    5.  *  
    6.  * 
    7.  *  
    8.  */  
    9. public class DataContainer {  
    10.     // 请求回应码  
    11.     private int errCode;  
    12.     // 主题数据类  
    13.     private Data data;  
    14.   
    15.     public Data getData() {  
    16.         return data;  
    17.     }  
    18.   
    19.     public void setData(Data data) {  
    20.         this.data = data;  
    21.     }  
    22.   
    23.     public int getErrCode() {  
    24.         return errCode;  
    25.     }  
    26.   
    27.     public void setErrCode(int errCode) {  
    28.         this.errCode = errCode;  
    29.     }  
    30. }  
    场景测试类Clien.java:
    1. package TextMining.crawler;  
    2.   
    3. /** 
    4.  * 腾讯新闻爬虫程序测试类 
    5.  *
    6.  * 
    7.  */  
    8. public class Client {  
    9.     public static void main(String[] args){  
    10.         //每次评论请求数量  
    11.         int reqNum;  
    12.         //总评论数  
    13.         int totalCommentCount;  
    14.         //评论的输出路径  
    15.         String outputPath;  
    16.         //腾讯新闻页url链接  
    17.         String newsUrl;  
    18.         QQNewsCrawler crawler;  
    19.           
    20.         reqNum = 50;  
    21.         totalCommentCount = 100;  
    22.         newsUrl = "http://news.qq.com/a/20150508/004453.htm";  
    23.         outputPath = "C:\Users\hadoop\Desktop\test\newsComments2.txt";  
    24.           
    25.         crawler = new QQNewsCrawler(newsUrl, totalCommentCount, reqNum, outputPath);  
    26.         crawler.crawlNewsComments();  
    27.     }  
    28. }  
  • 相关阅读:
    消息路由的构成
    消息的构造
    消息传递通道
    消息传递系统
    EXtJS Ext.data.Model
    oracle coherence介绍及使用
    LINUX下安装和配置WEBLOGIC10.0.3
    WebLogic中"域"的概念
    WebLogic中的一些基本概念
    下属有能力却不服管,你该怎么办?
  • 原文地址:https://www.cnblogs.com/hd-zg/p/4924350.html
Copyright © 2011-2022 走看看