当前位置:Gxlcms > html代码 > 给产品经理讲技术|一步一步写爬虫之网页分析_html/css_WEB-ITnose

给产品经理讲技术|一步一步写爬虫之网页分析_html/css_WEB-ITnose

时间:2021-07-01 10:21:17 帮助过:27人阅读

【文章摘要】爬虫说白了就是一个脚本程序。说到脚本,我们平时遇到一些费时费力又容易出错的活儿,都可以把用到的命令写到脚本里,让计算机自动来执行。

【相关推荐】

给产品经理讲技术|向前兼容、向后兼容

给产品经理讲技术|产品经理应该这样提需求之“状态机”

给产品经理讲技术|撩妹技术三部曲之“设计模式”

给产品经理讲技术丨没线,并不可怕?

给产品经理讲技术丨提需求的正确姿势是什么

还记得之前文章里说的要把所有文章整理成pdf的计划吗?今天我们准备迈出第一步了。

既然确定了用爬虫来自动整理文章,你得先理解爬虫是什么。爬虫说白了就是一个脚本程序。说到脚本,我们平时遇到一些费时费力又容易出错的活儿,都可以把用到的命令写到脚本里,让计算机自动来执行。测试同学说的自动化脚本,运维同学说的环境配置脚本,都是这个意思。一个脚本包含了很多命令,一个接一个,告诉计算机第一步干什么,之后干什么,最后干什么。

在这里,我们的目标很明确,就是写一个爬虫脚本,让计算机一步一步的把「给产品经理讲技术」的所有历史文章,保存成pdf。

历史文章哪里去找?正好,微信公众号的关注界面有一个查看历史消息的链接。

点开历史消息,这个页面每次显示10篇文章,如果用户滑到底,就会再加载10篇出来,典型的异步加载。我们要找的,就是每篇文章的URL地址。只要找到所有文章的URL,就能下载到每篇文章的内容和图片,然后就可以进一步加工处理成pdf了。

为此,我们长按页面选择在浏览器中打开,然后把地址栏里的URL复制出来,发送到电脑上,用Chrome打开。用Chrome的最大好处,就是它有一个「开发人员工具」,可以直接查看网页的源码。按下command+option+L,打开开发人员工具,就能看到这个网页的源码了。我们要找的东西,就藏在这些乱七八糟的HTML代码里。

如何从HTML源码里找到我们想要的文章链接呢?

这要从HTML的结构说起。HTML全称超文本标记语言,所谓标记,就是说是它通过很多标签来描述一个网页。你看到很多像以开始,以结束的标志,就是标签。这些标签一般成对出现,标签里面还可以套标签,表示一种层级关系。最外面的html标签是最大的,head、body次之,一层一层下来,最后才是一段文字,一个链接。你可以把它类比成一个人,这个人叫html,有head,有body,body上有hand,hand上面有finger。

扯远了,一些常用的标签:

1、。一个网页的很多重要信息,都是在这里声明的。比如说标题,就是在下的里定义的。一个网页用到的CSS样式,可以在<head>下的<style>里定义。还有你写的JavaScript代码,也可以在<head>下的<script>里定义。</p> <p>2、<body>。它包含的东西就多了,基本上我们能看到的东西,一段文字,一张图片,一个链接,都在这里面。比如说:</p> <ul> <li><p>表示一个段落</li> <li><h2>是一段文字的大标题</li> <li>表示一个链接</li> <li><img>表示一张图</li> <li><form>是一个表单</li> <li><div>是一个区块</li> </ul> <p>计算机是如何理解HTML的标签的呢?其实很简单,它就是一棵树。你可以把<html>当做树根,从树根上分出<head>和<body>,各个分支上又有新的分支,直到不能再分为止。这有点类似我们电脑上存放的文件。假设你有一本《21天学习C++》的电子书,存在D盘、study文件夹下的CS文件夹里。而study文件夹里除了CS文件夹,还有GRE、岛国文化等目录,代表着另一个分支体系。这也是一棵树。树上的每一片叶子,都有一条从根部可以到达的路径,可以方便计算机去查找。</p> <p>回到正题,有了这些基础知识,我么再来看微信这个历史消息页面。从最外层的<html>标签开始,一层一层展开,中间有<body>、有<div>、最后找到一个标签,标签里面的hrefs就是每篇文章的URL了。把这个URL复制下来,在新的TAB打开,确认确实是文章的地址。</p> <p> </p> <p>现在我们通过分析一个网页的结构、标签,找到了我们想要的文章URL,我们就可以写爬虫去模拟这个过程了。爬虫拿到网页之后,我们可以用正则表达式去查找这个标签,当然,也可以用一些更高级的手段来找。但是,这个页面里面毕竟只有10篇文章,我们还要研究它的延迟加载机制,想办法让爬虫能自动找到剩下的文章,这里面会涉及到网络抓包相关的知识,我们后面再聊。 </p> <p> 欢迎添加微信公众号:给产品经理讲技术 </p> <p> </p> <p> <p>本文由产品壹佰为你推荐并呈现</p> <p>文章来源:微信公众号:给产品经理讲技术(ID:pm_teacher)</p> <p>文章作者:果果</p> <p>友情提示:</p> <p>若出处标注错误,请联系QQ:2977686517及时更正,感谢理解和支持!</p> </p> <p> 少年关注我们的官方微博@产品100和微信订阅号:chanpin100ghsd,有惊喜哦! </div> <div class=""> <ul class="m-news-opt fix"> <li class="opt-item"> <a href='/htmldaima-263808.html' target='_blank'><p>< 上一篇</p><p class="ellipsis">信不信由你加这个前缀能避免与HTML以后版本的冲突_html/css_WEB-ITnose</p></a> </li> <li class="opt-item ta-r"> <a href='/htmldaima-263810.html' target='_blank'><p>下一篇 ></p><p class="ellipsis">iframe高度自适应内容_html/css_WEB-ITnose</p></a> </li> </ul> </div> </div> </div> <div class="g-title fix"> <h2 class="title-txt">人气教程排行</h2> </div> <div class="m-rank u-dashed mb40"> <ul> <li class="rank-item"> <a href="/htmldaima-274978.html" title='如何生成一个调查问卷_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">230次</span> <span class="g-sort-num top">1</span> 如何生成一个调查问卷_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-274080.html" title='在页面直接显示日历_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">230次</span> <span class="g-sort-num second">2</span> 在页面直接显示日历_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-262106.html" title='如何点击a标签实现弹出inputfile上传文件对话框_HTML/Xhtml_网页制作' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">230次</span> <span class="g-sort-num third">3</span> 如何点击a标签实现弹出inputfile上传文件对话框_HTML/Xhtml_网页制作 </a> </li> <li class="rank-item"> <a href="/htmldaima-278863.html" title='关于列表标记的详细介绍' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">229次</span> <span class="g-sort-num ">4</span> 关于列表标记的详细介绍 </a> </li> <li class="rank-item"> <a href="/htmldaima-277331.html" title='cssborder-bottom(指定下边线的样式、宽度及颜色)' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">229次</span> <span class="g-sort-num ">5</span> cssborder-bottom(指定下边线的样式、宽度及颜色) </a> </li> <li class="rank-item"> <a href="/htmldaima-270548.html" title='html新闻详情页_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">229次</span> <span class="g-sort-num ">6</span> html新闻详情页_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-268070.html" title='为何页面内容和网页边缘有空隙_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">229次</span> <span class="g-sort-num ">7</span> 为何页面内容和网页边缘有空隙_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-269054.html" title='position:fixed定位时“高度坍塌”问题的解决_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">228次</span> <span class="g-sort-num ">8</span> position:fixed定位时“高度坍塌”问题的解决_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-280863.html" title='htmlp标签怎么换行?htmlp标签添加br换行标签的应用' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">227次</span> <span class="g-sort-num ">9</span> htmlp标签怎么换行?htmlp标签添加br换行标签的应用 </a> </li> <li class="rank-item"> <a href="/htmldaima-281519.html" title='HTML的<!DOCTYPE>标签' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">226次</span> <span class="g-sort-num ">10</span> HTML的<!DOCTYPE>标签 </a> </li> <li class="rank-item"> <a href="/htmldaima-280725.html" title='html页面中友情链接怎么进行添加设置?(代码示例)' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">226次</span> <span class="g-sort-num ">11</span> html页面中友情链接怎么进行添加设置?(代码示例) </a> </li> <li class="rank-item"> <a href="/htmldaima-278651.html" title='form表单中属性及功能应用介绍汇总' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">226次</span> <span class="g-sort-num ">12</span> form表单中属性及功能应用介绍汇总 </a> </li> <li class="rank-item"> <a href="/htmldaima-278586.html" title='详解form标签中的method属性' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">226次</span> <span class="g-sort-num ">13</span> 详解form标签中的method属性 </a> </li> <li class="rank-item"> <a href="/htmldaima-277758.html" title='HTML5Canvas逼真烟雾效果js插件' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">226次</span> <span class="g-sort-num ">14</span> HTML5Canvas逼真烟雾效果js插件 </a> </li> <li class="rank-item"> <a href="/htmldaima-275669.html" title='页面跳转特效_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">226次</span> <span class="g-sort-num ">15</span> 页面跳转特效_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-271209.html" title='改变鼠标选中区域的样式。_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">226次</span> <span class="g-sort-num ">16</span> 改变鼠标选中区域的样式。_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-273428.html" title='关于$("body").append()一段html代码,在页面写能触发事件,写在js文件里写就没有_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">225次</span> <span class="g-sort-num ">17</span> 关于$("body").append()一段html代码,在页面写能触发事件,写在js文件里写就没有_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-271182.html" title='CSS3悬浮动画效果_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">225次</span> <span class="g-sort-num ">18</span> CSS3悬浮动画效果_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-271093.html" title='纯C语言实现的CSS解析器:katana_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">225次</span> <span class="g-sort-num ">19</span> 纯C语言实现的CSS解析器:katana_html/css_WEB-ITnose </a> </li> <li class="rank-item"> <a href="/htmldaima-267953.html" title='body在默认情况下是具有margin外边距的_html/css_WEB-ITnose' class="item-name ellipsis" target="_blank"> <span class="g-art-count fr">225次</span> <span class="g-sort-num ">20</span> body在默认情况下是具有margin外边距的_html/css_WEB-ITnose </a> </li> </ul> </div> </div> </div> <!-- / 教程内容页 --> </div> </div> <!-- 页尾 --> <div class="footer"> 本站所有资源全部来源于网络,若本站发布的内容侵害到您的隐私或者利益,请联系我们删除!</div> <!-- / 页尾 --> <script type="text/javascript" src="/kan/js/read.js"></script> <div style="display:none"> <div class="login-box" id="login-dialog"> <div class="login-top"><a class="current" rel="nofollow" id="login1" onclick="setTab('login',1,2);" >登录</a></div> <div class="login-form" id="nav-signin"> <!-- <div class="login-ico"><a rel="nofollow" class="qq" id="qqlogin" target="_blank" href="/user-center-qqlogin.html"> QQ </a></div> --> <div class="login-box-form" id="con_login_1"> <form id="loginform" action="/user-center-login.html" method="post" onsubmit="return false;"> <p class="int-text"> <input class="email" id="username" name="username" type="text" value="用户名或Email" onfocus="if(this.value=='用户名或Email'){this.value='';}" onblur="if(this.value==''){this.value='用户名或Email';};" ></p> <p class="int-text"> <input class="password1" type="password" id="password" name="password" value="******" onBlur="if(this.value=='') this.value='******';" onFocus="if(this.value=='******') this.value='';" > </p> <p class="int-info"> <label class="ui-label"> </label> <label for="agreement" class="ui-label-checkbox"> <input type="checkbox" value="" name="cookietime" id="cookietime" checked="checked" value="2592000"> <input type="hidden" name="notforward" id="notforward" value="1"> <input type="hidden" name="dosubmit" id="dosubmit" value="1">记住我的登录 </label> <a rel="nofollow" class="aright" href="/user-center-forgetpwd.html" target="_blank"> 忘记密码? </a></p> <p class="int-btn"><a rel="nofollow" id="loginbt" class="loginbtn"><span>登录</span></a></p> </form> </div> <form id="regform" action="/user-center-reg.html" method="post"> <div class="login-reg" style="display: none;" id="con_login_2"> <input type="hidden" name="t" id="t"/> <p class="int-text"> <input id="email" name="email" type="text" value="Email" onfocus="if(this.value=='Email'){this.value='';}" onblur="if(this.value==''){this.value='Email';};"></p> <p class="int-text"> <input id="uname" name="username" type="text" value="用户名或昵称" onfocus="if(this.value=='用户名或昵称'){this.value='';}" onblur="if(this.value==''){this.value='用户名或昵称';};"></p> <p class="int-text"> <input type="password" id="pwd" name="password" value="******" onBlur="if(this.value=='') this.value='******';" onFocus="if(this.value=='******') this.value='';"> </p> <p class="int-text1"><span class="inputbox"> <input id="validate" name="validate" type="text" value="验证码" onfocus="if(this.value=='验证码'){this.value='';}" onblur="if(this.value==''){this.value='验证码';};"> </span><span class="yzm-img"><img src="/user-checkcode-index" alt="看不清楚换一张" id="indexlogin"></p> <p class="int-info"> <label> <input value="" name="agreement" id="agreement" CHECKED="checked" type="checkbox"> 我已阅读<a rel="nofollow" href="/user-center-agreement.html">用户协议</a>及<a rel="nofollow" href="/user-center-agreement.html">版权声明</a></label> </p> <p class="int-btn"><input type="hidden" name="dosubmit"/> <a rel="nofollow" class="loginbtn" id="register"><span>注册</span></a></p> </div> </form> </div> </div> </div> </div> <script type="text/javascript" src="/kan/js/foot_js.js"></script> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?6dc1c3c5281cf70f49bc0bc860ec24f2"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script> <script type="text/javascript" src="/layui/layui.js"></script> <script> layui.use('code', function() { layui.code({ elem: 'pre', //默认值为.layui-code about: false, skin: 'notepad', title: 'php怎么实现数据库验证跳转代码块', encode: true //是否转义html标签。默认不开启 }); }); </script> </body> </html>