软件园学生在线

  • {{ item.name }}
  • 2023试用期

登录与注册

【后端二】高靖原

  • 高 靖原
  • 2022-10-22
  • 0

Java爬虫学习

一. 学习历程

HTML语言

  1. HTML是一种超文本语言(HyperText Markup Language),是一种标记语言,而非编程语言,HTML编写的文件在浏览器渲染后就成为了我们所看到的网页界面(在网页界面点击F12即可显示该网页的HTML格式)
  2. HTML主要包括<code class="prettyprint" >和两部分,head部分主要包括标题、脚本、样式等信息,body部分包括网页的主体信息
  3. 除<code class="prettyprint" >和标签外,还有其他的一些标签,如标题为<code class="prettyprint" >,段落为</code> <p><code class="prettyprint" >,换行为</code><br /><code class="prettyprint" >,这些标签都可以在</code><code class="prettyprint" >或</code></code>下使用</li> </ol> <h3>java方法</h3> <ol> <li> <p>java为了使程序员写代码更加方便,定义了一个java标准类库,里面有各种类,以及各种方法,都是平时写代码时容易用到的,需要使用时直接通过类名和方法名直接调用,有些类在使用时需要import声明</p> </li> <li> <p>方法的命名,我们在需要使用一些java标准类库中没有的方法时,需要自己创建一个类,在创建方法时需要命名方法名,第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符,标准的方法名有助于理解记忆方法的用途</p> </li> <li> <p>方法的写法,编写方法时的格式如下,注意最后返回值的类型应该和头部声明的类型相同,没有返回值时头部应为void</p> <pre><code class="prettyprint" > 修饰符 返回值类型 方法名(参数类型 参数名){ ... 方法体 ... return 返回值; }</code></pre> <h3>正则表达式</h3> </li> <li> <p>正则表达式是一种用来匹配的表达式,比如,在某个网页的搜索框中输入指定格式的表达式,网页就会标记出该格式的字符</p> </li> <li> <p>举个例子<code class="prettyprint" >^\d+(\.\d+)?</code><strong>^</strong> 定义了以什么开始,即标志着正则表达式的开始,\d表示匹配一个随机的0~9数字,\d+表示一个或多个数字,.表示小数点,则.\d+就表示小数,()?表示可有可无,这些合在一起就表示一个整数或小数</p> </li> <li> <p>·pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。在我理解它就是定义了一会要匹配的格式<br /> ·matcher对象可以对输入的表达式进行解释,同时根据表达式进行匹配</p> </li> </ol> <h3>Jsoup和爬虫</h3> <ol> <li>在进行爬虫前需要新建maven项目以及在pom中导入依赖,但依赖具体是干什么的我也不是很清楚,就不多说了</li> <li>Jsoup可以用来连接某网站获取html文档,<code class="prettyprint" >Document document = Jsoup.connect("https://www.xbiquge.so/book/10415/").get();</code>此行代码可以通过Jsoup连接到小说网站获得其html文档</li> <li> <p>css选择器,可以帮你选择指定网页html文档中的指定标签内容, 如下第一行代码可以选择到dl下的dd标签的所有内容,第二行可以选择到a标签具有herf属性的标签</p> <pre><code class="prettyprint" > Elements menu = document.body().select"dl dd"; Elements as = menu.select("a[herf]");</code></pre> </li> </ol> <h2>二. 问题存疑</h2> <ol> <li>爬取出的小说只有文本,换行符空格那些完全没有,导致爬出来后时一团,很难受,始终做不到可以把换行符一起爬出来,也有想过用css选择器选择<br />标签,然后爬出来,但是不知道怎么把换行符和文本一起爬出来</li> <li>还有就是目录问题,目录我就是把每节的标题爬下来了,然后做了超链接,让他链接到各自的网页上,但是,它依旧很乱,不晓得怎么把它搞得整齐,好看一点(我是把爬出来的小说保存成md形式了)</li> </ol> <h2>三.代码</h2> <pre><code class="prettyprint" > import org.jsoup.nodes.Element; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; import java.io.*; import java.util.Scanner; public class Main { public static void main(String[] args) throws IOException { /* * 声明一些常量、变量 */ String menuUrl = "https://www.aixiaxsw.com/111/111972/";//默认目录页 final String fileAddr = "./"; Scanner scanner = new Scanner(System.in); System.out.println("输入1则根据下次输入的目录URL爬取(URL模板示例:https://www.aixiaxsw.com/111/111972/),输入2则爬取示例小说《超能星武》"); if(scanner.nextInt()==1) { menuUrl = scanner.next(); if(menuUrl.startsWith("www.aixiaxsw.com")) menuUrl = "https://" + menuUrl; if(!menuUrl.endsWith("/")) menuUrl = menuUrl + "/"; if(!menuUrl.startsWith("http://www.aixiaxsw.com")){ if(!menuUrl.startsWith("https://www.aixiaxsw.com")){ System.out.println("请输入爱下书小说网小说目录的URL\n请稍后重新输入"); System.exit(0); } } } /* * 访问目录页,获取小说名、章节名、章节链接 */ Document document = null;//新建一个文档 try { document = Jsoup.connect(menuUrl).get(); } catch (IOException ewww) { ewww.printStackTrace(); } String title = document.body().selectFirst("h1").text(); String author = document.body().selectFirst("p").text(); System.out.println("开始爬取:"+title); Elements menu = document.body().select("dl dd");//选择父元素为dl的所有dd标签 Elements as = menu.select("a[href]"); /* * 新建文件、文件流 */ System.out.println("小说将保存在:"+fileAddr + title+".md 中"); File file = new File(fileAddr + title+".md"); OutputStream fileOut = null; try { fileOut = new FileOutputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } // 在向文件中输出每一章节前,先输出小说名 fileOut.write(("#"+title+"\n"+"*"+author+"*"+"\n\n"+"##目录##"+"\n\n").getBytes()); /*保存目录到文件中 * */ System.out.println("正在爬取小说目录..."); int count1 = 1; for(Element a : as){ if(count1<=9){ count1++; continue; } String chapterName = a.text(); String subLink = a.attr("href"); fileOut.write(("["+chapterName + "](https://www.aixiaxsw.com/"+subLink+")" + " ").getBytes()); } fileOut.write(("\n\n##正文##").getBytes()); /* * 保存每个章节的正文到文件中 */ int count = 1; //循环操作每个章节 for (Element a : as){ if(count<=9){ count++; continue; } //跳过最新章节 String subLink = a.attr("href"); //章节链接 String chapterName = a.text(); //章节名称 System.out.println("当前爬取章节:"+chapterName); Document chapter = null; try { chapter = Jsoup.connect("https://www.aixiaxsw.com/"+subLink).timeout(10000).get(); } catch (IOException ewww) { ewww.printStackTrace(); } Element chapterContent = chapter.selectFirst("#content"); fileOut.write(("\n\n###" + chapterName + "###\n\n " + chapterContent.text()).getBytes()); } System.out.println("小说爬取完成"); fileOut.close(); } }</code></pre> <div class="saboxplugin-wrap" itemtype="http://schema.org/Person" itemscope itemprop="author"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt='高 靖原' src='https://cravatar.cn/avatar/504746e6990ba1813482c83dc3e93a42c16d548947ded95ec93ab1afd40dc281?s=100&d=identicon&r=g' srcset='https://cravatar.cn/avatar/504746e6990ba1813482c83dc3e93a42c16d548947ded95ec93ab1afd40dc281?s=200&d=identicon&r=g 2x' class='avatar avatar-100 photo' height='100' width='100' itemprop="image"/></div><div class="saboxplugin-authorname"><a href="https://blog.sduonline.cn/post/author/jingyuan" class="vcard author" rel="author"><span class="fn">高 靖原</span></a></div><div class="saboxplugin-desc"><div itemprop="description"></div></div><div class="clearfix"></div></div></div> </article> </section> <section id="comments"></section> <script> window.ArticleData = { el: '#comments', post_id: 2501, author_information: true, // 作者信息 adjacent_articles: false, // 相邻文章 editor: { placeholder: 'Comment', // 编辑器提示文字 features: ['emoji', 'bold', 'italic'], // 编辑器功能 }, hyperlinks: true, // 评论者链接 pagination: { rows: 10, // 每页评论数 rolling: true, // 滚动加载 autoload: false, // 自动加载 }, visitor: [], // 访客信息 author: {"display_name":"\u9ad8 \u9756\u539f","description":"","avatar":"https://cravatar.cn/avatar/504746e6990ba1813482c83dc3e93a42c16d548947ded95ec93ab1afd40dc281?s=96&d=identicon&r=g"}, // 作者信息 }; $h.tasks.comments = () => { const $config = window.ArticleData || {}; $h.store.comments = new Vue({ el: $config.el, mixins: [$modules.CommentArea], data() { return { ...$config }; }, }); } </script></div><!-- content --> </main><!-- main --> </section><!-- core --> <footer id="footer"> <div class="d-flex flex-center justify-between"> <div class='left'> <span>© 2025 <a href="https://blog.sduonline.cn">软件园学生在线</a></span> </div> <div class='right'> <span>Theme by <a class="theme-name" href="https://biji.io" target="_blank">Wing</a></span> </div> </div> </footer> <script data-no-instant> function _exReload() { window.Lately && Lately.init(); window.ViewImage && ViewImage.init(); window.prettyPrint && prettyPrint(); } </script> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"\/*"},{"not":{"href_matches":["\/wp-*.php","\/wp-admin\/*","\/wp-content\/uploads\/*","\/wp-content\/*","\/wp-content\/plugins\/*","\/wp-content\/themes\/Wing\/*","\/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script type="text/javascript" src="//cdn.staticfile.org/vue/2.6.14/vue.min.js?ver=0.6.0" id="vue-js"></script> <script type="text/javascript" src="//cdn.staticfile.org/prettify/r298/prettify.js?ver=0.6.0" id="prettify-js"></script> <script type="text/javascript" src="https://blog.sduonline.cn/wp-content/themes/Wing/static/package.js?ver=0.6.0" id="package-js"></script> <script type="text/javascript" src="https://blog.sduonline.cn/wp-content/themes/Wing/static/modules.js?ver=0.6.0" id="modules-js"></script> <script type="text/javascript" id="script-js-extra"> /* <![CDATA[ */ var BaseData = {"origin":"https:\/\/blog.sduonline.cn","avatar":"\/\/cn.gravatar.com\/avatar","ajax":"https:\/\/blog.sduonline.cn\/wp-admin\/admin-ajax.php","rest":"https:\/\/blog.sduonline.cn\/wp-json\/","nonce":"fc19d34fac"}; /* ]]> */ </script> <script type="text/javascript" src="https://blog.sduonline.cn/wp-content/themes/Wing/static/script.js?ver=0.6.0" id="script-js"></script> <script id="module-katex"> (function($) { $(function() { if (typeof katex !== "undefined") { if ($(".language-katex").length > 0) { $(".language-katex").parent("pre").attr("style", "text-align: center; background: none;"); $(".language-katex").addClass("katex-container").removeClass("language-katex"); $(".katex-container").each(function() { var katexText = $(this).text(); var el = $(this).get(0); if ($(this).parent("code").length == 0) { try { katex.render(katexText, el) } catch (err) { $(this).html("<span class='err'>" + err) } } }); } if ($(".katex-inline").length > 0) { $(".katex-inline").each(function() { var katexText = $(this).text(); var el = $(this).get(0); if ($(this).parent("code").length == 0) { try { katex.render(katexText, el) } catch (err) { $(this).html("<span class='err'>" + err) } } }); } } }); })(jQuery); </script> <script id="module-highlight-js"> (function($) { $(function() { $("pre code").each(function(i, e) { var thisclass = $(this).attr("class"); if (typeof thisclass !== "undefined") { if ( thisclass.indexOf("katex") === -1 && thisclass.indexOf("mermaid") === -1 && thisclass.indexOf("seq") === -1 && thisclass.indexOf("flow") === -1 ) { if (typeof hljs !== "undefined") { $(this).closest("pre").addClass("hljs"); hljs.highlightBlock(e); } else { console.log("%c WP Githuber MD %c You have enabled highlight.js modules already, but you have to update this post to take effect, identifying which file should be loaded.\nGithuber MD does not load a whole-fat-packed file for every post.", "background: #222; color: #bada55", "color: #637338"); } } } }); }); })(jQuery); </script> <script id="module-mathjax" > (function($) { $(function() { if (typeof MathJax !== "undefined") { var c = $(".language-mathjax").length; if (c > 0) { $(".language-mathjax").each(function(i) { var content = $(this).html(); if ($(this).hasClass("mathjax-inline")) { $(this).html("$ " + content + " $"); } else { $(this).html("$$" + "\n" + content + "\n" + "$$"); } if (i + 1 === c) { MathJax.Hub.Config({ showProcessingMessages: false, messageStyle: "none", extensions: [ "tex2jax.js", "TeX/mediawiki-texvc.js", "TeX/noUndefined.js", "TeX/autoload-all.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js" ], jax: [ "input/TeX", "output/SVG" ], elements: document.getElementsByClassName("language-mathjax"), tex2jax: { skipTags: [ "script", "noscript", "style", "textarea" ], inlineMath: [ ['$', '$'] ], displayMath: [ ['$$', '$$'] ], processClass: "language-mathjax" } }); MathJax.Hub.Queue(["Typeset", MathJax.Hub]); $(".language-mathjax").attr("style", "background: transparent; border: 0;"); $(".language-mathjax").closest("pre").attr("style", "background: transparent; border: 0;"); } }); } else { console.log("[wp-githuber-md] MathJax code blocks not found."); } } else { console.log("[wp-githuber-md] MathJax is not loadded."); } }); })(jQuery); </script> <!--网站效率:1.124秒内查询了39次数据库--> </body> </html>