设为首页 收藏本站
查看: 1153|回复: 0

[经验分享] 利用Python抓取CSDN博客

[复制链接]

尚未签到

发表于 2015-12-1 10:59:23 | 显示全部楼层 |阅读模式
  这两天发现了一篇好文章,陈皓写的makefile的教程,具体地址在这里《跟我一起写makefile》
  这篇文章一共分成了14个部分,我看东西又习惯在kindle上面看,感觉一篇一篇地复制成txt文本太弱了,索性就用python写了一个小爬虫,把这些文章全部都下载下来。
  
  这个程序主要可以分成这么几块内容,获取,分析,转换。
  程序的整体结构如下图所示:
DSC0000.png
  get_html.py程序的功能就是实现获取功能,将下载到的原始的html文件都存放到ori_html文件夹中。ana_html.py程序实现了上面的分析和转换两个功能,通过分析原始html文件,将包含正文的div块提取出来,存放到div_html文件夹的html文件中,再利用lynx函数将这些html文本转换成txt文本,存放到text文件夹中。
  
  第一,获取。
  这一步做的事情就是把这几篇文章的html文件全部都下载下来。这个就是构造一个http请求,然后请求回来一个html页面就好了。需要注意的就是这几篇文章存放路径的编号。比如第一篇文章,它的链接是这个:http://blog.csdn.net/haoel/article/details/2886,最后编号是2886。第二篇文章的链接是这个:http://blog.csdn.net/haoel/article/details/2887。最后编号是2887。至于最后一篇文章,第14篇文章的链接是这个:http://blog.csdn.net/haoel/article/details/2899,最后的编号是2899。相信从这里大家可以看出规律来了吧,从第一篇文章到最后一篇文章,存放路径的编号依次就是从2886到2899递增。那我下载html页面的时候,其实就是只要把这个编号不断递增,就可以把所有14篇文章都给下载下来了。具体代码如下:



1 #!/usr/bin/env python
2 # -* - coding: UTF-8 -* -
3
4 import httplib
5 from time import sleep
6
7 def writeFile(html,list_num):
8     filename = "./ori_html/htmlfile%d.html" % list_num
9     file_obj = open(filename,"w")
10     file_obj.write(html)
11     file_obj.close()
12     print "%s文件已经写入" % filename
13 def getHTML(list_num):
14     print '准备获取%d号HTML文档成功' % list_num
15     url = "http://blog.csdn.net/haoel/article/details/%d" % list_num
16     conn = httplib.HTTPConnection("blog.csdn.net")
17     conn.request(method="GET",url=url)
18     response = conn.getresponse()
19     res= response.read()
20     print '获取%d号HTML文档成功' % list_num
21     writeFile(res,list_num)
22 def getHTMLs():
23         for num in range(2886,2900):
24             sleep(1)
25            getHTML(num)
26
27 getHTMLs()
  主函数getHTMLs通过调用getHTML来下载多个页面。每下载完一个页面,就暂停一秒钟,这是为了防止访问速度过快,让服务器认定这是攻击行为,把本机IP给屏蔽掉了。getHTML函数就是根据不同的编号,下载不同的页面,然后将下载到的页面存放到ori_html文件夹中,意思就是原始的html文件(original html)。
  
  第二,分析
  上面把所有的html文件都给下载好了,但是并不是这个页面的所有的内容都是我们想要的,我们只想要中间的正文部分,如下图所示:
DSC0001.png
  在这个页面中我们只想要那个画红线的部分。
  这个要具体怎么做呢,就是通过chrome分析原界面,可以看到中间的正文部分是通过一个id为article_content的div来表示的,如下图所示,
DSC0002.png
  我们只要把这个div给获取出来了,那么就能得到正文内容了。
  获取了这个div之后,再把它存放到一个html文件中,然后再来通过lynx命令,就能把这个篇文章下载到本地了,具体代码如下:



1 #!/usr/bin/env python
2 # -* - coding: UTF-8 -* -
3
4 from bs4 import BeautifulSoup
5 import os
6
7 def readFile(filename):
8         print "read the %s" % filename
9         file_obj = open(filename,"r")
10         html = file_obj.read()
11         file_obj.close()
12         return html
13
14 def writeFile(html,list_num):
15         filename = "./div_html/div_html_%d.html" % list_num
16         if os.path.exists(filename):
17                 print "%s 已经存在" % filename
18                 return -1
19         file_obj = open(filename,"w")
20         print >> file_obj,html
21         print "%s已经写入" % filename
22
23 def formFile(list_num):
24         outnum = list_num - 2886 + 1
25         filename = "./div_html/div_html_%d.html" % list_num
26         outname = "text/makefile_%d.txt" % outnum
27         cmd = "lynx --dump %s > %s" % (filename,outname)
28         os.system(cmd)
29         print "%s已经写入" % outname
30
31 def main():
32         for num in range(2886,2900):
33                 filename = "./ori_html/htmlfile%d.html" % num
34                 if not os.path.exists(filename):
35                         print "%s donn't exist" % filename
36                         continue
37                 html_doc = readFile(filename)
38                 soup = BeautifulSoup(html_doc)
39                 div_html = soup.find_all("div",id="article_content")
40                 writeFile(div_html[0],num)
41                 formFile(num)
42
43 main()
  在主函数中通过for循环依次遍历每个文件,readFile函数的功能就是读取html文件内的html代码存放到html_doc里面。然后再通过bs4的find_all方法,找到id为article_content的div节点。这里返回的结果是一个tag元素列表,所以底下给writeFile函数传递的参数为div_html[0],将这个tag元素传递进去。
  在writeFile函数中,将传递进来的tag元素的所有内容都写入到div_html文件夹的文件中。然后再在formFile(格式化文件,format file)函数中,利用lynx命令,将这个包含正文的div转换成txt文本,写入到text文件夹的文本文件中去。
  这里需要注意的一点就是writeFile函数中,将print函数打印的内容写入文件的方法直接就是print >> 文件对象名,print的参数,这样相当于做了一个数据流重定向,将本应打印到屏幕上的东西打印到文件中去了。
  
  最后下载下来的文档如下所示:
DSC0003.png
  OK,就是这么多了。这个程序写的比较仓促,感觉程序中还有许多冗余的地方,欢迎各位指正!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-145788-1-1.html 上篇帖子: Python——thread 下篇帖子: python检测服务器是否ping通
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表