新浪微博爬虫——非登陆非API半自动爬虫

随着项目进展,现在已写出全自动新浪微博爬虫程序,并开发成图形界面工具。感兴趣的朋友可浏览我的系列文章:

全自动非登陆非API新浪微博爬虫2.0——(1)综述和获取有效代理IP。
全自动非登陆非API新浪微博爬虫2.0——(2)Jsoup解析HTML及其他代码。
全自动非登陆非API新浪微博爬虫2.0——(3)新浪微博爬虫图形界面工具开发

文章原创声明:

此文章为李雪山原创,转载引用请保留此声明头,并注明出处。

引用网址为本文章链接:http://blog.csdn.net/codingmirai/article/details/17754645

尊重原创,共同学习,感谢分享。

如有疑问,可联系hainanlxs(at)gmail(dot)com

 

程序使用方法和运行结果:

文章里的所有代码组成一个java文件,import相关包即可运行。相关包为httpcomponents-client-4.3.1,dom4j-1.6.1请官网下载或点这里:百度网盘相关jar包

有时间我会把程序再写成软件。

 

  1. import java.awt.Desktop;
  2. import java.awt.Toolkit;
  3. import java.io.BufferedReader;
  4. import java.io.BufferedWriter;
  5. import java.io.File;
  6. import java.io.FileReader;
  7. import java.io.FileWriter;
  8. import java.io.IOException;
  9. import java.net.URI;
  10. import java.net.URISyntaxException;
  11. import java.util.Vector;
  12. import java.util.regex.Matcher;
  13. import java.util.regex.Pattern;
  14. import org.apache.http.client.ClientProtocolException;
  15. import org.apache.http.client.config.CookieSpecs;
  16. import org.apache.http.client.config.RequestConfig;
  17. import org.apache.http.client.methods.CloseableHttpResponse;
  18. import org.apache.http.client.methods.HttpGet;
  19. import org.apache.http.config.Registry;
  20. import org.apache.http.config.RegistryBuilder;
  21. import org.apache.http.cookie.Cookie;
  22. import org.apache.http.cookie.CookieOrigin;
  23. import org.apache.http.cookie.CookieSpec;
  24. import org.apache.http.cookie.CookieSpecProvider;
  25. import org.apache.http.cookie.MalformedCookieException;
  26. import org.apache.http.impl.client.CloseableHttpClient;
  27. import org.apache.http.impl.client.HttpClients;
  28. import org.apache.http.impl.cookie.BestMatchSpecFactory;
  29. import org.apache.http.impl.cookie.BrowserCompatSpec;
  30. import org.apache.http.impl.cookie.BrowserCompatSpecFactory;
  31. import org.apache.http.protocol.HttpContext;
  32. import org.apache.http.util.EntityUtils;
  33. import org.dom4j.DocumentHelper;
  34. import org.dom4j.Element;
  35. import org.dom4j.io.OutputFormat;
  36. import org.dom4j.io.XMLWriter;

 

 

程序功能为爬取新浪微博搜索页面(s.weibo.com)的微博。在main方法里设置要搜索的关键词和要搜索的页数,运行程序即可爬取相应页面的html文件。然后解析html文件得到微博文本,可以保存微博文本为xml格式或者txt格式。此程序在连接搜索页面时为未登录状态,每爬取20页需要输入验证码。程序设置了链接超时,未连接成功会自动重连,当需要输入验证码时,蜂鸣警报并自动弹出填写验证码页面,可设置程序暂停时间,在这个时间里填写验证码,之后程序继续运行。

程序每小时大约能爬取25000-30000条微博(时间大部分花在超时重连和手动填写验证码上了。)

例如以“假哈佛校训”(2014年1月2日下午2点左右微博热门话题)为例,爬取五十页此关键字的搜索结果页面,得到835条不重复的微博,1020条相关微博的id。

下面是程序运行的一些截图:

下面详细介绍过程:

思路很简单:

1.      用httpClient爬取想要的微博搜索结果页面,得到html文件并保存。例如此以“港独”为搜索关键字在s.weibo.com里搜索,注意网页地址参数:http://s.weibo.com/weibo/%E6%B8%AF%E7%8B%AC&nodup=1&page=50

2.      得到html文件后解析出微博内容。按照需要可以解析该页面呈现的所有信息,我只是解析了微博文本。

对我来说,此程序的难点在html的解析上。我自己比较满意的地方是抓取不成功时可以自动重连,遇到验证码时自动弹出填写验证码页面,伴随蜂鸣提醒。

主要工具是httpClient4.3.1,一个关于网络的强大的java工具包。

详细的程序实现:

1.      getHTML方法

输入url地址,返回此url的String形式html。用httpClient 4.3.1写get方法十分简单。可以查看httpClient的官方tutorial,document下有在线的,也有pdf版本的。

这里有两个要点。

一是设置用户cookie策略(custom cookie policy,以下代码第到行),可以屏蔽掉cookie rejected的报错。不过这只是让这个错误不在控制台报错(不那么烦人),实际上并没有解决。你也可以不设置,直接用默认的client,即用CloseableHttpClient httpClient = HttpClients.createDefault();创建的客户端,会报错,如下:

 

二是设置socket超时(socketTimeout暂不明白,弄懂后再修改)和连接超时超时(connectTimeout)。这一点很重要,如果不设置,当网速不好,某次请求没有得到及时响应的时候,程序就会卡死在这一步。所以client一次请求不成功,自己并不会自动重连,而是卡死。设置连接超时,当超时后再重连,有效解决这个问题。

  1.     /**
  2.      * 由url得到html
  3.      * @param url
  4.      * @return html
  5.      * @throws URISyntaxException
  6.      * @throws ClientProtocolException
  7.      * @throws IOException
  8.      */
  9.     private String getHTML(Stringurl)throwsURISyntaxException, ClientProtocolException, IOException {
  10.         // TODO Auto-generated methodstub
  11.         //采用用户自定义cookie策略,只是使cookie rejected的报错不出现,此错误仍然存在
  12.         CookieSpecProvidereasySpecProvider = new CookieSpecProvider() {
  13.             public CookieSpeccreate(HttpContext context) {
  14.                 returnnew BrowserCompatSpec() {
  15.                     @Override
  16.                     publicvoid validate(Cookie cookie,CookieOrigin origin)
  17.                             throwsMalformedCookieException {
  18.                         // Oh, I am easy
  19.                     }
  20.                 };
  21.             }
  22.         };
  23.         Registry<CookieSpecProvider>r = RegistryBuilder
  24.                 .<CookieSpecProvider>create()
  25.                 .register(CookieSpecs.BEST_MATCH,new BestMatchSpecFactory())
  26.                 .register(CookieSpecs.BROWSER_COMPATIBILITY,
  27.                         newBrowserCompatSpecFactory())
  28.                 .register(“easy”,easySpecProvider).build();
  29.         RequestConfigrequestConfig = RequestConfig.custom()
  30.                 .setCookieSpec(“easy”)
  31.                 .setSocketTimeout(5000)//设置socket超时时间
  32.                 .setConnectTimeout(5000)//设置connect超时时间
  33.                 .build();
  34.         CloseableHttpClienthttpClient = HttpClients.custom()
  35.                 .setDefaultCookieSpecRegistry(r)
  36.                 .setDefaultRequestConfig(requestConfig).build();
  37. //      CloseableHttpClienthttpClient = HttpClients.createDefault();//若不自定义cookie策略,则报错cookie rejected
  38. //      RequestConfigrequestConfig = RequestConfig.custom()
  39. //              .setSocketTimeout(5000)
  40. //              .setConnectTimeout(5000)
  41. //              .build();
  42.         HttpGethttpGet = newHttpGet(url);
  43.         httpGet.setConfig(requestConfig);
  44.         Stringhtml = “html获取失败”;//用于验证是否正常取到html
  45.         try{
  46.             CloseableHttpResponseresponse = httpClient.execute(httpGet);
  47.             html= EntityUtils.toString(response.getEntity());
  48.             //System.out.println(html);//打印返回的html
  49.         }catch(IOExceptione){
  50.             System.out.println(“****连接超时,程序自动重连****”);
  51.         }
  52.         return html;
  53.     }   /**

 

2.getWeibo方法,输入上一步保存的html微博路径,输出此html中的所有不重复微博的Vector<String>。本来解析一个html文件,jsoup是个利器,但是得到的html文件中,微博句子被封装在一段javascript代码中(见图),jsoup派不上太大用场,虽然他也能定位到script节点(<script>/</script>),然后再使用正则匹配,但是意义不大,所以只用java.util里的Pattern和Matcher就好了。如果熟练掌握正则表达式的话解析起来会比较快。自己对正则匹配的语法一直不是很熟悉,费老劲了,一定要熟练掌握这个实用的工具。

提取微博所在<em><\/em>结构的时候有个地方需要注意,就是当此微博是评论转发的时候,比如下图:

会出现一个<em>后有两个<\/em>,即<em>和<\/em>并非成对出现,这时候要注意提取最相邻两个<em><\/em>中的内容。提取之后将这个结构中所有的<xxx>都去掉,得到的就是微博的utf8码了。再用Integer.parseInt(utf8CodeStr,16)将一个个utf8十六进制数字转成char,再拼起来。具体的匹配解析方法在代码中,这里一定要仔细观察html文件以便解析。

这条微博在html的<em><\/em>中是嵌套的,

  1. private Vector<String> getWeibo(String htmlPath)throws IOException {
  2.         // TODO Auto-generated method stub
  3.         Filef = newFile(htmlPath);
  4.         FileReaderfr = newFileReader(f);
  5.         BufferedReaderbr = newBufferedReader(fr);
  6.         Vector<String>utf8weibos = newVector<String>();
  7.         Strings;//<em>{1}.+(color:red){1}.+<\\\\/em>{1}
  8.         Stringhtml = “”;
  9.         Patternp = Pattern.compile(“<em>.+?color:red.+?<\\\\/em>”);//微博utf-8包含在<em>/</em>体中
  10.         Stringutf8weibotemp = null;
  11.         while ((s = br.readLine()) !=null){//读html文件为String
  12.             html= html + s;
  13.         }
  14.         br.close();
  15.         Matcherm = p.matcher(html);
  16.         while(m.find()){
  17.             utf8weibotemp= m.group();
  18.             //过滤掉转发的微博。分析html的结果,防止转发嵌套。substring中的3是为了跨过嵌套的<em>,可为1或2或3或4
  19.             Matchermm = p.matcher(utf8weibotemp.substring(3));
  20.             if(mm.find()){
  21.                 utf8weibotemp= mm.group();
  22.             }
  23.             utf8weibos.add(utf8weibotemp);
  24.         }
  25.         Vector<String>realweibos = newVector<String>();
  26.         for(int i = 0; i <utf8weibos.size(); i++){//输入含有微博的<em>/</em>标签体
  27.             String weibotemp = utf8weibos.get(i);
  28.             Pattern pcancel = Pattern.compile(“<.+?>”);//要去除掉所有<>号的内容(包括<>号本身)
  29.             Matcher mcancel =pcancel.matcher(weibotemp);
  30.             Vector<String> cancel = new Vector<String>();//存待删除的<>
  31.             while(mcancel.find()){
  32.             if(!cancel.contains(mcancel.group())){
  33.                  cancel.add(mcancel.group());
  34.                  //System.out.println(m.group());
  35.             }
  36.             }
  37.             //System.out.println(weibo);//输出清理<>后的微博
  38.             for(int j = 0; j <cancel.size(); j++){//实施清理<>
  39.                  weibotemp= weibotemp.replace(cancel.get(j), “”);
  40.             }
  41.             //System.out.println((char)Integer.parseInt(“548c”,16));//得到结果为,汉字“和”
  42.             weibotemp= weibotemp.replace(“/”,””);//去掉”/”
  43.             weibotemp= weibotemp.replace(“\\u”,”李李雪雪山山”);//先将utf8标志\\u替换成一个比较独特的东西,方便下一步
  44.                 weibotemp = weibotemp.replace(“\\”,””);//去掉所有的\,
  45.                 weibotemp = weibotemp.replace(“李李雪雪山山”,”\\u”);//把utf8替换回来
  46.                 weibotemp = weibotemp.replace(“””,”\\\””);//把html里的引号标示符”换成正常的引号
  47.                 StringBuilder sb = new StringBuilder();
  48.                 Pattern utf8p = Pattern.compile(“\\\\u[0-9a-f]{4}”);//识别汉字utf-8编码码文
  49.                 Matcher utf8m =utf8p.matcher(weibotemp);
  50.                 String utf8CodeStr;
  51.                 while (utf8m.find()){
  52.                   utf8CodeStr= utf8m.group().substring(2);//把\\uxxxx(汉字)中的16进制xxxx取出
  53.                       sb.append((char)Integer.parseInt(utf8CodeStr,16));//xxxx转成汉字本身
  54.                   //System.out.println(utf8m.group());
  55.                 }
  56.                 //System.out.println(sb.toString());
  57.                 if(!realweibos.contains(sb.toString())){//保存不重复的微博
  58.                   realweibos.add(sb.toString());
  59.                 }
  60.             }
  61.         return realweibos;
  62.     }

最关键的就是以上两步,以下简略说明在实际编程中我用到的其他方法:

3. isValidHTML方法,输入getHTML中得到的html,判断是否是有效的搜索页面,返回boolean,true则有效,可以进行提取,false无效,需要重新连接这个无效html的url。页面无效的原因有两个,一是指定到的页数不存在。新浪对每个搜索,给出最新前五十页微博,每页20条微博,当搜索词不那么热门的时候,便没有这么多页,例如以“李雪山”为关键词进行搜索(http://s.weibo.com/weibo/%E6%9D%8E%E9%9B%AA%E5%B1%B1&nodup=1&page=50)得到如下返回:

找到“您可以尝试更换关键词,再次搜索。”这句话在html中的位置,(如图),以此句为标志判断页面无效。

同理,当需要验证码输入时,返回的页面在上面有贴出。同样可以以“你的行为有些异常,请输入验证码:”为检查是否有效的标志。

  1. private boolean isValidHTML(Stringhtml) throwsInterruptedException {
  2.       // TODO Auto-generated method stub
  3.       boolean isValid =false;
  4.           PatternpNoResult = Pattern.compile(“\\\\u60a8\\\\u53ef\\\\u4ee5\\\\u5c1d\\\\u8bd5”
  5.                   +”\\\\u66f4\\\\u6362\\\\u5173\\\\u952e\\\\u8bcd\\\\uff0c\\\\u518d\\\\u6b21″
  6.                   +”\\\\u641c\\\\u7d22\\\\u3002″);//您可以尝试更换关键词,再次搜索。(表示指定页没有结果)
  7.           PatternpVerify = Pattern.compile(“\\\\u4f60\\\\u7684\\\\u884c\\\\u4e3a\\\\u6709”
  8.                   +”\\\\u4e9b\\\\u5f02\\\\u5e38\\\\uff0c\\\\u8bf7\\\\u8f93\\\\u5165\\\\u9a8c”
  9.                   +”\\\\u8bc1\\\\u7801\\\\uff1a”);//你的行为有些异常,请输入验证码(被系统检测出你是机器,会蜂鸣提示,刷新微博输入验证码就可以继续了)
  10.           MatchermNoResult = pNoResult.matcher(html);
  11.           if(!mNoResult.find()){//如果搜索页面存在,则往下判断是否需要输入验证码
  12.                   MatchermVerity = pVerify.matcher(html);
  13.                   if(!mVerity.find()){
  14.                       isValid= true;
  15.                   }
  16.           }
  17.       return isValid;
  18.   }

4. runBroswer方法,输入url,调用默认浏览器弹出该url页面。当需要输入验证码时,自动弹出默认浏览器验证码地址,手工填写。(这就是我所谓的半自动,杯具。。。)

  1. /**
  2.  * 用默认浏览器打开指定网址
  3.  * @param url
  4.  * @throws URISyntaxException
  5.  * @throws IOException
  6.  */
  7. private void runBroswer(String url) throws URISyntaxException,IOException {
  8.         Desktop desktop = Desktop.getDesktop();
  9.         if (Desktop.isDesktopSupported()&& desktop.isSupported(Desktop.Action.BROWSE)) {
  10.             URI uri = new URI(url);
  11.             desktop.browse(uri);
  12.             }
  13. }

 

 

 

5. getWeiboIDs方法,输入String类型html,返回匹配到的mid,也就是微博id。这是我随便写的一个方法,可以用这些微博id作为调用微博API的参数,得到官方返回的数据,比如微博或者评论等等。用了vector的contains方法来去重,但是这些id并不只是那20条微博的id,只要是出现的微博,包括转发嵌套里的,都会包含。

  1. /**
  2.  * 由html文件得到weibo id
  3.  * @param html
  4.  * @return weibo ids
  5.  * @throws IOException
  6.  */
  7. private Vector<String>getWeiboIDs(String htmlFile)throws IOException {
  8.     // TODO Auto-generated method stub
  9.     Vector<String>IDs = newVector<String>();
  10.     Filef = newFile(htmlFile);
  11.     FileReaderfr = newFileReader(f);
  12.     BufferedReaderbr = newBufferedReader(fr);
  13.     Stringhtml = “”;
  14.     Strings;
  15.     while((s = br.readLine()) !=null){
  16.         html= html + s;
  17.     }
  18.     br.close();
  19.     Patternp = Pattern.compile(“mid=[0-9]{16}”);//mid共有十六位
  20.     Matcherm = p.matcher(html);
  21.     Stringmid;
  22.     while (m.find()) {
  23.         mid= m.group().substring(m.group().indexOf(“mid=”)+4);
  24.         if (!IDs.contains(mid)) {
  25.             IDs.add(mid);
  26.         }
  27.     }
  28.     return IDs;
  29. }

6. 几个简单的写文件操作,合在一起写了吧。其中有个写xml文件的,用的是dom4j包,也比较简单,有时间会另外专门介绍。

  1. private void writeString(String s,String savePath) throwsIOException {
  2.         // TODO Auto-generated method stub
  3.         File f = new File(savePath);
  4.         FileWriter fw = new FileWriter(f);
  5.         BufferedWriter bw = new BufferedWriter(fw);
  6.         bw.write(s);
  7.         bw.close();
  8.     }
  9. /**
  10.      * 把某关键字搜索到的微博全写到文件中去
  11.      * 这里简单写成了txt格式
  12.      * @param vector
  13.      * @param savePath
  14.      * @throws IOException
  15.      */
  16.     private voidwriteVector(Vector<String> vector, String savePath) throws IOException {
  17.         // TODO Auto-generated method stub
  18.         Filef = newFile(savePath);
  19.         FileWriterfw = newFileWriter(f);
  20.         BufferedWriterbw = newBufferedWriter(fw);
  21.         for (int i = 0; i <vector.size(); i++) {
  22.             bw.write(vector.get(i)+”\r\n”);
  23.         }
  24.         bw.close();
  25.     }
  26.     private voidwriteVector2xml(Vector<String> vector, String savePath) throws IOException {
  27.         // TODO Auto-generated method stub
  28.         int vectorSize =vector.size();
  29.         OutputFormatformat = OutputFormat.createPrettyPrint();
  30.         format.setEncoding(“GB2312”);//将xml格式定义为gb2321,这样才能识别。默认是utf8,不能识别
  31.         Filef = newFile(savePath);
  32.         f.createNewFile();//先建一个空xml文件
  33.         FileWriterfw = newFileWriter(f);
  34.             org.dom4j.Documentdocument = DocumentHelper.createDocument();//建document对象实例
  35.             ElementrootElement = document.addElement(“weibos”);//节点增加方法
  36.             rootElement.addAttribute(“totalNumber”,String.valueOf(vectorSize));//设置属性
  37.             for (int j = 0; j <vectorSize; j++) {
  38.                 ElementweiboElement = rootElement.addElement(“weibo”);
  39.                 weiboElement.addAttribute(“polarity”,”unknown”);
  40.                 weiboElement.addAttribute(“opinionated”,”unknown”);
  41.                 weiboElement.setText(vector.get(j).toString());//设置节点文本内容
  42.             }
  43.             XMLWriterxw = newXMLWriter(fw,format);
  44.             xw.write(document);//写document到xml文件
  45.             xw.close();
  46.     }

7. 最后是main方法,把以上方法组织起来就好了。Main写得不是很简洁,在程序设计方面我啥也不懂。。。

  1. public staticvoidmain(String[] args) throws ClientProtocolException,
  2.     URISyntaxException,IOException, InterruptedException {
  3.         WeiboCrawler2crawler = newWeiboCrawler2();
  4.         String[]searchwords = {“港独” };
  5.         for (int n = 0; n <searchwords.length;n++) {
  6.             Stringsearchword = searchwords[n];
  7.             Filef = newFile(“d:/data/weibo/getweibo/”+searchword);
  8.             f.mkdir();//创建文件夹,另一方法mkdirs创建多层未创建的文件夹
  9.             Stringhtml;
  10.             StringsaveWeibosTXTPath = “d:/data/weibo/saveweibo/weibostxt/”+searchword+”.txt”;
  11.             StringsaveWeibosXMLPath = “d:/data/weibo/saveweibo/weibosxml/”+searchword+”.xml”;
  12.             StringsaveWeibosIDsPath = “d:/data/weibo/saveweibo/weibosIDtxt/”+searchword+”_IDs.txt”;
  13.             int totalPage = 50;//设置想要搜索的页数,则搜索范围为该搜索词下的第1到第totalPage页
  14.             System.out.println(“****开始爬取 \””+searchword+”\”关键字的微博****”);
  15.             /**
  16.              * 此循环将指定页数的搜索页面html文件爬取下来并保存
  17.              */
  18.             for(int i = totalPage; i >0; i–){//开始爬取,先把一个话题下的html都爬下来,再用这些html文件
  19.                 //System.out.println(i);//处理到第i页
  20.                 html= crawler.getHTML(
  21.                         “http://s.weibo.com/weibo/”+searchword+”&nodup=1&page=”+String.valueOf(i));
  22.                 if(html !=”html获取失败”){
  23.                     if(crawler.isValidHTML(html)){
  24.                         crawler.writeString(html,
  25.                                 “d:/data/weibo/getweibo/”+searchword+”/”+searchword+String.valueOf(i)+”.html”);
  26.                         System.out.println(“获取第”+i+”页成功!”);
  27.                     }
  28.                     else{
  29.                         System.out.println(“****十秒内请在弹出页面输入验证码,程序会自动重连****”);
  30.                         Toolkit.getDefaultToolkit().beep();//蜂鸣提示需要输入验证码
  31.                         crawler.runBroswer(“http://s.weibo.com/weibo/%25E6%259D%258E%25E9%259B%25AA%25E5%25B1%25B1hakka&Refer=index”);
  32.                         Thread.sleep(10000);//你有十秒时间可以填入验证码
  33.                         i++;
  34.                     }
  35.                 }
  36.                 else {//如果因为连接超时问题,获得的html为”html获取失败”的话,则再重新连接一次
  37.                     i++;
  38.                 }
  39.             }
  40.             System.out.println(“****爬取 \””+searchword+”\”微博结果结束****”);
  41.             Vector<String>oneHTMLWeibos = newVector<String>();//一个html下的所有微博
  42.             Vector<String>oneHTMLWeiboIDs = new Vector<String>();//一个html下的所有微博的id
  43.             Vector<String>allWeibos = newVector<String>();//一个关键词搜索出来的所有微博
  44.             Vector<String>allWeiboIDs = newVector<String>();//所有微博的id
  45.             /**
  46.              * 此循环从搜索页面html文件中得到微博,微博id,存入向量容器中
  47.              */
  48.             for (int i = 1; i <totalPage+1; i++) {
  49.                 StringhtmlFile = “d:/data/weibo/getweibo/”+searchword+”/”+searchword+String.valueOf(i)+”.html”;
  50.                 Filefile = newFile(htmlFile);
  51.                 if(file.isFile()){//如果这个文件存在,就解析出微博来
  52.                     oneHTMLWeibos= crawler.getWeibo(htmlFile);
  53.                     oneHTMLWeiboIDs= crawler.getWeiboIDs(htmlFile);
  54.                 }
  55.                 for (int j = 0; j < oneHTMLWeiboIDs.size();j++) {//存到总微博id里
  56.                     if(!allWeiboIDs.contains(oneHTMLWeiboIDs.get(j))){
  57.                         allWeiboIDs.add(oneHTMLWeiboIDs.get(j));
  58.                     }
  59.                 }
  60.                 for (int j = 0; j <oneHTMLWeibos.size(); j++) {//存到总微博里
  61.                     if(!allWeibos.contains(oneHTMLWeibos.get(j))){
  62.                         allWeibos.add(oneHTMLWeibos.get(j));
  63.                     }
  64.                 }
  65.             }
  66.             /**
  67.              * 将结果写入文件
  68.              */
  69.             crawler.writeVector(allWeibos,saveWeibosTXTPath);
  70.             crawler.writeVector2xml(allWeibos,saveWeibosXMLPath);
  71.             crawler.writeVector(allWeiboIDs,saveWeibosIDsPath);
  72.             Toolkit.getDefaultToolkit().beep();
  73.             Thread.sleep(500);
  74.             Toolkit.getDefaultToolkit().beep();//响两声表示爬取一个关键词结束
  75.         }
  76.         Toolkit.getDefaultToolkit().beep();
  77.         Thread.sleep(500);
  78.         Toolkit.getDefaultToolkit().beep();
  79.         Thread.sleep(500);
  80.         Toolkit.getDefaultToolkit().beep();//响三声提示一下爬取结束
  81.     }
  82. }

Tagged: , ,

Comments are closed.