书接上文,今天一起来学习把网页版文章下载到本地电脑上。
前面讲过,请求网页的流程是浏览器先向服务器请求html,服务器返回html,浏览器分析这个html,发现html中还需要一堆的js,css,图片,然后浏览器再去下载这些文件,最终组装成一个完整的html页面。
所以,第一步,要把这个html下载下来。
是时候请出大家期待已久的python了,我在讲解的过程中只列出核心代码,完整代码会列在文章最后,所以强烈建议先把整篇文章看完了再动手自己敲代码。其他文章也是相同的逻辑,以后不再重复。
需要用到一个鼎鼎大名的第三方库 requests ,用它来模拟浏览器给微信服务器发送请求和接收请求。
那么发送的请求中都要包含什么内容呢?
上文介绍chrome开发者工具时提过这个问题,奥秘在Headers这个标签中,见下图,理论上来讲chrome浏览器发送了什么我们的最好就原样照着用python发送什么,即把下图所示的General 和 Request Headers 块中的参数全都发送出去。但多数时候并不需要这样,特别是对于get请求,一般只需要少数几个参数即可,但是请注意User-Agent这一项一定要改得跟chrome一样。其他细节不再多述,过后您操作的多了自然会明白。
简单的注释会直接在代码中列出,复杂的会在代码后面用文字再解释,另外本文的原始稿是在微信公众号后台编辑生成的,直接复制粘贴到其他平台格式会全乱掉,所以使用了图片的形式,见谅。
运行上面代码之前,请先手动在C盘下新建vWeChatFiles文件夹,本项目之后下载的所有文件都放在此目录下,请注意这里是保存下载的网页文件的,而你的python源代码可以放在其他目录下。
运行上面的代码,你将看到屏幕刷刷得显示一堆网页源代码,并且在c:/vWeChatFiles文件夹下生成一个test.html文件。
下面,来看这个下载下来的test.html能否正常工作,请先打开chrome,按F12,弹出开发者工具,在最上面一行标签中切换到 Network,然后在chrome 的网页中输入C:/vWeChatFiles/test.html,回车。可能需要等几十秒,看到了刚才我们下载的网页。
同时chrome开发者工具显示如下图所示
有许多行是红色的,表示这些文件下载失败了,刚才之所以等了好久网页才显示出来就是因为浏览器在尝试等待这些文件的下载,等过了一段时间还是没有等到对的人,它说那就算了吧,我只把接收到的内容显示出来。
所以,仔细查看加载出来的test.html,文字显示正常,格式也正常,但是没图片啊。其实这个图片没显示的原因比较复杂,先不展开讲。
在test.html网页的空白处右键,点"查看网页源代码",chrome中会打开一个新窗口,显示这个网页的原始源代码,此处的源代码,跟用记事本打开test.html文件所看到的源代码是一样的。
但是,这些原始代码跟开发者工具中 Elements 中显示的,即下图右侧显示的格式化的网页代码可能不一样。比如下图箭头所指位置的“1周前”,虽然你在右侧的源代码中也看到了“1周前”,但是在最原始的代码中此处并没有“1周前”。
其实右侧显示的代码是原始源代码被浏览器打开之后运行了js程序计算出来的网页结构代码。搞明白两种源代码的不同之处,可以帮初学者减少许多迷惑。
然而奇怪的是,看源代码对应的<img />标签中竟然没有 src 属性,而开发者工具中的<img /> 中的src是一堆奇怪的文字,并不像一个网址。(不过至少此处再次印证了上文我说的两处的源代码有可能并不一致)
稍延伸一下,上图所示的src中的一串字符其实是表示一张图片,一张用文本表示的简单图片,有兴趣的朋友可以自行百度,顺便告诉你一个好消息:百度竟然不要钱。
这些都不管了,直接把src改成正确的图片网址吧。可是,图片网址在哪里呢?请再仔细看上面的一张图, data-src 好像是一个网页,把这一串网页复制出来,粘贴到浏览器地址栏中打开,神奇的事情发生了:竟然是文章中的一张高清无码大图。那我们就有理由相信,这就是原本此处要显示的图片的网址,可它为啥藏着掖着,而不是直接给src设置好呢?这是个好问题,知道答案的朋友请在文章下方留言,我送你上墙。
下面,就把此网页中所有图片标签<img /> 中的 data-src 的网址赋给src,需要用到另一个优秀的第三方库 BeautifulSoup,它可以解析网页中的元素,并对它们进行修改、增加、删除等操作。下面只列出了改变过、需要重点查看的部分,并不是完整代码,所以你直接保存复制是运行不起来的,但如果加在上面给出的源代码的后面就能跑起来(当然要小改一些地方,再次提醒读者需要有一点编程基础)。
注意第21行,有的图片会以 //http://res.wx.qq.com开头,需要换成常见的http://res.wx.qq.com 形式开头,否则本地打开网页时这些图片会无法正常加载。至于为什么会有 // 开头的网址您可以自行百度。
C:\vWeChatFiles文件夹下会有一个test2.html文件,在chrome中打开,网页可以正常显示了,但是开发者工具中依然显示有许多请求是红字状态,先不用管。
接下来的问题是,虽然图片可以在网页中显示了,但src是一个网址,图片是在每次打开网页时从远程服务器下载的,并没有保存到本地,如果远程文章被删了图片就没法看了。
接下来我们要做的是:把图片下载到本地,并在html中把图片的src指向本地图片的位置。
主要代码如下,需要先在vWeChatFiles目录下新建一个images文件夹
至此,网页保存到本地基本完成,其实还有几个小问题,比如:
引用样式表时也是用到了 // 开头的网址,聪明的你仿照图片的修改方法去修改这里应该不是问题,就当是小小的练习了。
又比如:开发者工具中看到许多 js 文件加载失败,但并不影响网页显示,且过后会专门处理js,所以先不用管。
请注意,本示例代码为了方便大家理解,许多地方用了硬编码,且都堆在一个文件中,这不是最佳方式,甚至可以说是糟糕的方式,但在现阶段代码不多的情况下这不是啥问题,大家先把注意力集中在功能的实现上即可。
下一篇:中国互联网公司亏损能力排行榜