• 爬虫学习的一个综合案例——访问网站


    1.一些回顾知识和补充

    URL基础讲解_說書人的博客-CSDN博客

    详解HttpURLConnection_清箫的博客-CSDN博客_httpurlconnection

    一个是URL,一个是HeepURLConnection:

    任何网络连接都需要经过socket才能连接,HttpURLConnection不需要设置socket,所以,HttpURLConnection并不是底层的连接,而是在底层连接上的一个请求。这就是为什么HttpURLConneciton只是一个抽象类,自身不能被实例化的原因。HttpURLConnection只能通过URL.openConnection()方法创建具体的实例。
     

    这里请求头的话有Get 、Post,

    GET请求和POST请求详述_bear*6的博客-CSDN博客_get请求和post的用法

    GET 请求和 POST 请求的区别与使用示例 - 隔壁汪书 - 博客园

    爬虫在setRequestProperty传入的:

    User-Agent(用户代理)是什么_睿科知识云的博客-CSDN博客_user-agent

    正则:

    正则表达式中关于 \ 的用法,例如\. \(_懶好人vest的博客-CSDN博客_正则表达式\

    正则 ?= 用法_风神修罗使的博客-CSDN博客_?= 正则

    正则表达式中?=和?:和?!的理解_这个昵称没有被占用吧的博客-CSDN博客_正则表达式?!

    接口和实现类

    接口 对象 = new 实现类 与 实现类 对象= new 实现类_代码敲上天.的博客-CSDN博客_new 实现类

    接口如何实现多态_晓晓小仙儿的博客-CSDN博客_接口多态

    实现多态的方式——接口 - 走看看

    Set set=new HashSet();的意义是什么呢_谜的博客的博客-CSDN博客

    Collection解释:
    1.实现了Collection接口
    2.类型一定是E的子类

    ?是“任意类”的意思,extends继承不多说,E是指定类型,是泛型;
    通常出现在将一个集合赋值给另一个集合的情景中,

    如:public LinkedList(Collection c )、addAll(Collection c);

    addAll方法——向Set集合添加另一个集合的所有内容_xk_一步一步来的博客-CSDN博客_addall方法

    2.究极详细的代码分析

    1. public class UrlCrawBoke {
    2. static String userId = "";
    3. public static void main(String urlstr[]) throws IOException, InterruptedException {
    4. //set是接口,hashset是它的实现类
    5. //接口 对象 = new 实现类,见笔记,主要是为了实现多态,虽然这里不需要多态,但是这是良好的代码习惯
    6. Set urls = new HashSet();
    7. // ----------------------------------------------遍历每一页 获取文章链接----------------------------------------------
    8. //该引用为常量,该值无法修改
    9. final String homeUrl = "https://blog.csdn.net/" + userId + "/article/list/";// 后面加pageNum即可
    10. //统计页数
    11. int totalPage = 0;
    12. //接受从网页爬取的内容
    13. InputStream is;
    14. //把网页内容转为string
    15. String pageStr;
    16. //网站地址索引
    17. StringBuilder curUrl = null;
    18. for (int i = 1; i < 50; i++) {
    19. //暂停1秒
    20. Thread.sleep(1000);
    21. //找页数,如果写的文章多,那就有两页三页......
    22. System.out.println("finding page " + i);
    23. //初始化网站地址索引
    24. curUrl = new StringBuilder(homeUrl);
    25. //完善地址,加上页码
    26. curUrl.append(i);
    27. System.out.println(curUrl);
    28. //爬取网站内容
    29. is = doGet(curUrl.toString());
    30. //转成string
    31. pageStr = inputStreamToString(is, "UTF-8");// 一整页的html源码
    32. //正则表达式,这里是来获取每一篇博客的网址,按照规律来,detaiLs后面会跟8-9个数字,
    33. //又因为在博客目录下,要访问具体博客,我们鼠标点的是图标文字,但是实际上点的是超链接,也就是这个网页的静态资源里面html文本中必然是有href
    34. //所以(?<=href=\")表示匹配以href="开头的字符串,并且捕获(存储)到分组中,\"写在正则里面就是表示",\是引用符
    35. //而最后面的(?=\")表示匹配以"结尾的字符串,并且捕获(存储)到分组中,这样就把具体博客的网址拿下来了
    36. List list = getMatherSubstrs(pageStr, "(?<=href=\")https://blog.csdn.net/" + userId + "/article/details/[0-9]{8,9}(?=\")");
    37. //把网址加进去
    38. /*这里的addall,有点东西的
    39. 首先首先,集合collection是最上层滴接口
    40. 然后set是collection的子接口
    41. 再然后Hashset是set其中一个实现类
    42. 然后按道理应该addall方法要在hashset中实现
    43. 但是呢,hashset不仅实现set还继承了abstractset这个抽象类
    44. 然后abstractset这个抽象类继承AbstractCollection(当然也实现了set)
    45. 所以最后最后呢,addall这个玩意是在AbstractCollection这个抽象类里面实现的,这也是为什么我们查找实现查到AbstractCollection去了
    46. */
    47. //addall就是把list的内容全部添加到urls里去
    48. urls.addAll(list);
    49. //总页数
    50. totalPage = i;
    51. //如果pagestr里面没有空空如也这四个字,那就返回-1,至于空空如也是因为csdn里面如果没有博客那就会出现这里空空如也
    52. //但是这网页有时候也脑抽的,不一定每次都吃
    53. if (pageStr.lastIndexOf("空空如也") != -1) {
    54. System.out.println("已经到最后一页!");
    55. break;
    56. } else {
    57. System.out.println("Success~");
    58. }
    59. }
    60. System.out.println("总页数为: " + totalPage);
    61. // ---------------------------------------------------打印每个链接---------------------------------------------------
    62. System.out.println("打印每个链接");
    63. for (Object s:urls) {
    64. System.out.println(s);
    65. }
    66. System.out.println("打印每个链接完毕");
    67. // ---------------------------------------------------访问每个链接---------------------------------------------------
    68. int i=0;
    69. for (Object s:urls) {
    70. //传入网址进行访问
    71. doGet(s.toString());
    72. System.out.println("成功访问第" + (++i) + "个链接,共" + urls.size() + "个:" + s);
    73. }
    74. // ---------------------------------------------------程序结束---------------------------------------------------
    75. System.out.println("运行完毕,成功增加访问数:" + urls.size());
    76. }
    77. public static InputStream doGet(String urlstr) throws IOException {
    78. //初始化URL
    79. URL url = new URL(urlstr);
    80. //打开URL链接,获得HttpURLConnection对象,下面的括号转化是有原理的,看看笔记
    81. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    82. //对链接进行设置(设置请求头或响应头)
    83. //setRequestProperty(key,value),后面只能跟一个value
    84. //setRequestProperty会覆盖已经存在的key的所有values,有清零重新赋值的作用
    85. //User-Agent(用户代理),详情看笔记
    86. conn.setRequestProperty("User-Agent",
    87. "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
    88. //建立HttpURLConnection链接
    89. conn.connect();
    90. //读取网页内容(字符串流)(请求)(实际上也会隐式调用connect())
    91. InputStream inputStream = conn.getInputStream();
    92. //返回
    93. return inputStream;
    94. }
    95. //charset代表的是编码
    96. public static String inputStreamToString(InputStream is, String charset) throws IOException {
    97. //缓冲区
    98. byte[] bytes = new byte[1024];
    99. //长度
    100. int byteLength = 0;
    101. StringBuffer sb = new StringBuffer();
    102. //常见的读取操作
    103. while ((byteLength = is.read(bytes)) != -1) {
    104. //函数里面长度可以不写
    105. //这个string()源码很有意思,虽然看起来吃力,但是值得一看
    106. sb.append(new String(bytes, 0, byteLength, charset));
    107. }
    108. return sb.toString();
    109. }
    110. // 正则匹配
    111. public static List getMatherSubstrs(String str, String regex) {
    112. //获取链表
    113. List list = new ArrayList();
    114. //获取正则表达式对象
    115. Pattern p = Pattern.compile(regex);
    116. //获取文本匹配器m,拿着m,按p的规则去匹配str
    117. Matcher m = p.matcher(str);
    118. while (m.find()) {
    119. //循环获取
    120. list.add(m.group());
    121. }
    122. return list;
    123. }
    124. }

  • 相关阅读:
    Python串口小结1
    .Net DI(Dependency Injection)依赖注入机制
    Dynamsoft Barcode Reader新框架将医疗视觉提升到新水平
    算法进阶——数组中只出现一次的两个数字
    【雅思备考IELTS】美文阅读 艾米莉·勃朗特《呼啸山庄》Wuthering Heights by Emily Bronte
    一款功能强大、高颜值、官方出品的Redis可视化工具
    判断一个矩阵是另一个矩阵的子矩阵C++
    【Typescript综合】模块化开发
    金仓数据库KingbaseES备份与恢复工具手册(备份)
    tiobe的内容项怎么回事?
  • 原文地址:https://blog.csdn.net/keepstrivingchy/article/details/126007783