热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发记录_自学Python写爬虫程序爬取csdn个人博客信息

每天刷开csdn的博客,看到一整个页面,其实对我而言,我只想看看访问量有没有上涨而已于是萌生了一个想法:想写一个爬虫程序把csdn博客上边的访问量和评论数都爬下来。打算通过网

每天刷开csdn的博客,看到一整个页面,其实对我而言,我只想看看访问量有没有上涨而已...

于是萌生了一个想法:

想写一个爬虫程序把csdn博客上边的访问量和评论数都爬下来。

打算通过网络各种搜集资料,自学写Python代码。

这次自学的历程,也打算及时的整理下来,发布在博客里。

 

/******************这是程序员风格的分割线******************/

 

据说Python并不难,看过了python的代码之后也觉得确实,

代码很清爽,相比起C/C++,JS,PHP来讲,python的代码看起来就是舒服。

看了几段别人的爬虫程序教程,还不太清楚Python的编译器是怎么处理代码的。

每一句代码的分割似乎是通过换行,

像是if/else这样的多个语句在一起的,也没有看到大括号,而是像这样:

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">import urllib, urllister  
  2.   
  3. def getURL(url):  
  4.     try:  
  5.         usock = urllib.urlopen(url)  
  6.     except:  
  7.         print 'get url excepton'  
  8.         return []  
  9.     parser = urllister.URLLister()  
  10.     parser.feed(usock.read())  
  11.     usock.close()  
  12.     parser.close()  
  13.     urls = parser.urls  
  14.     return urls  


对于函数的定义,只要def就好了。

 

变量的申明只需要在用的时候起个名字就好了,不用规定int, char, float....

我是一个从C语言转学来的乡下孩子..这么高端洋气上档次的定义方式真是惊了个呆。

于是瞬间对Python好感倍增。

 

看了很多人的爬虫教程,以及代码,还是没什么思路,今天没空了,等明天上手试试看。

 

2013.11.4_第一步大功告成

不错不错,今天试了试网上的教程,成功的把我的博客主页抓下来了。

中间还遇上些坎坷,不过先感谢一下

 

月语凋凌 在他的百度空间 Endless Road 里转载的博客

用python爬虫抓站的一些技巧总结

据月语凋凌所说转自  http://gae-django-cms.appspot.com  不过我这里似乎打不开这个网页..

这篇文章真心的帮到了大忙,虽然小小吐槽一下排版不好..

在这里系统的学到了Python爬虫的入门部分。

这位博主请不要介意,我在这里帮你整理一下缩进,再整理一下代码方便大家吧~

<--注意:一直到下一个此类似标记前的内容,均转自月语凋凌 的博客用python爬虫抓站的一些技巧总结,我只是做了整理-->

 

 

原文转自http://gae-django-cms.appspot.com/

这些脚本有一个共性,都是和web相关的,总要用到获取链接的一些方法,再加上simplecd这 个半爬虫半网站的项目,

累积不少爬虫抓站的经验,在此总结一下,那么以后做东西也就不用重复劳动了。

 

1.最基本的抓站

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">import urllib2  
  2. content = urllib2.urlopen('http://XXXX').read()  

 

 

2.使用代理服务器

这在某些情况下比较有用,比如IP被封了,或者比如IP访问的次数受到限制等等。

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">import urllib2  
  2. proxy_support = urllib2.ProxyHandler({'http':'http://XX.XX.XX.XX:XXXX'})  
  3. opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)  
  4. urllib2.install_opener(opener)  
  5. content = urllib2.urlopen('http://XXXX').read()  


 

 

3.需要登录的情况

登录的情况比较麻烦我把问题拆分一下:

 

 

 

3.1 COOKIE的处理

 

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">import urllib2, COOKIElib  
  2. COOKIE_support= urllib2.HTTPCOOKIEProcessor(COOKIElib.COOKIEJar())  
  3. opener = urllib2.build_opener(COOKIE_support, urllib2.HTTPHandler)  
  4. urllib2.install_opener(opener)  
  5. content = urllib2.urlopen('http://XXXX').read()  


 

 

是的没错,如果想同时用代理和COOKIE,那就加入proxy_support然后operner改为

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">opener = urllib2.build_opener(proxy_support, COOKIE_support, urllib2.HTTPHandler)  

 

 

 

3.2 表单的处理

 

 

登录必要填表,表单怎么填?首先利用工具截取所要填表的内容

 

比如我一般用firefox+httpfox插件来看看自己到底发送了些什么包

 

这个我就举个例子好了,以verycd为例,先找到自己发的POST请求,以及POST表单项:

 

可以看到verycd的话需要填username,password,continueURI,fk,login_submit这几项,其中fk是随机生 成的(其实不太随机,看上去像是把epoch时间经过简单的编码生成的),需要从网页获取,也就是说得先访问一次网页,用正则表达式等工具截取返回数据中 的fk项。continueURI顾名思义可以随便写,login_submit是固定的,这从源码可以看出。还有username,password那 就很显然了。

 

-

 

好的,有了要填写的数据,我们就要生成postdata

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">import urllib  
  2. postdata=urllib.urlencode({  
  3.     'username':'XXXXX',  
  4.     'password':'XXXXX',  
  5.     'continueURI':'http://www.verycd.com/',  
  6.     'fk':fk,  
  7.     'login_submit':'登录'  
  8.     })  

 

 

然后生成http请求,再发送请求:

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">req = urllib2.Request(  
  2.     url = 'http://secure.verycd.com/signin/*/http://www.verycd.com/',  
  3.     data = postdata)  
  4. result = urllib2.urlopen(req).read()  

 

 

 

3.3 伪装成浏览器访问

 

 

某些网站反感爬虫的到访,于是对爬虫一律拒绝请求

 

这时候我们需要伪装成浏览器,这可以通过修改http包中的header来实现

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">headers = {  
  2.     'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'  
  3. }  
  4. req = urllib2.Request(  
  5.     url = 'http://secure.verycd.com/signin/*/http://www.verycd.com/',  
  6.     data = postdata,  
  7.     headers = headers  
  8. )  

 

 

 

3.4 反”反盗链”

 

 

某些站点有所谓的反盗链设置,其实说穿了很简单,就是检查你发送请求的header里面,referer站点是不是他自己,所以我们只需要像3.3一样, 把headers的referer改成该网站即可,以黑幕著称地cnbeta为例:

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">#...  
  2. headers = {  
  3.     'Referer':'http://www.cnbeta.com/articles'  
  4. }  
  5. #...  

 

 

headers是一个dict数据结构,你可以放入任何想要的header,来做一些伪装。例如,有些自作聪明的网站总喜欢窥人隐私,别人通过代理 访问,他偏偏要读取header中的X-Forwarded-For来看看人家的真实IP,没话说,那就直接把X-Forwarde-For改了吧,可以 改成随便什么好玩的东东来欺负欺负他,呵呵。

 

-

 

 

3.5 终极绝招

 

 

有时候即使做了3.1-3.4,访问还是会被据,那么没办法,老老实实把httpfox中看到的headers全都写上,那一般也就行了。

 

再不行,那就只能用终极绝招了,selenium直 接控制浏览器来进行访问,只要浏览器可以做到的,那么它也可以做到。类似的还有pamie,watir,等等等等。

 

-

 

 

4.多线程并发抓取

单线程太慢的话,就需要多线程了,这里给个简单的线程池模板
这个程序只是简单地打印了1-10,但是可以看出是并发地。

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">from threading import Thread  
  2. from Queue import Queue  
  3. from time import sleep  
  4. #q是任务队列  
  5. #NUM是并发线程总数  
  6. #JOBS是有多少任务  
  7. q = Queue()  
  8. NUM = 2  
  9. JOBS = 10  
  10. #具体的处理函数,负责处理单个任务  
  11. def do_somthing_using(arguments):  
  12.     print arguments  
  13. #这个是工作进程,负责不断从队列取数据并处理  
  14. def working():  
  15.     while True:  
  16.         arguments = q.get()  
  17.         do_somthing_using(arguments)  
  18.         sleep(1)  
  19.         q.task_done()  
  20. #fork NUM个线程等待队列  
  21. for i in range(NUM):  
  22.     t = Thread(target=working)  
  23.     t.setDaemon(True)  
  24.     t.start()  
  25. #把JOBS排入队列  
  26. for i in range(JOBS):  
  27.     q.put(i)  
  28. #等待所有JOBS完成  
  29. q.join()  



 

 

5.验证码的处理

碰到验证码咋办?这里分两种情况处理:

 

 

 

1.google那种验证码,

 

 

 

凉拌

 

 

2.简单的验证码:

 

 

字符个数有限,只使用了简单的平移或旋转加噪音而没有扭曲的,这种还是有可能可以处理的,一般思路是旋转的转回来,噪音去掉,然后划分 单个字符,划分好了以后再通过特征提取的方法(例如PCA) 降维并生成特征库,然后把验证码和特征库进行比较。这个比较复杂,一篇博文是说不完的,这里就不展开了,具体做法请弄本相关教科书好好研究一下。

 

 

3.事实上有些验证码还是很弱的,

 

 

这里就不点名了,反正我通过2的方法提取过准确度非常高的验证码,所以2事实上是可行的。

 

 

6.总结

基本上我遇到过的所有情况,用以上方法都顺利解决了。

 


<--注意:以上内容均转自月语凋凌 的博客用python爬虫抓站的一些技巧总结,我只是做了整理,以下内容为本人原创-->

 

利用这篇博客里的例子,我先模仿了一个自己的Python爬虫。

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">import urllib2  
  2. content = urllib2.urlopen('http://blog.csdn.net/yuri_4_vera').read()  

 

我是用Sublime Text2 作为编辑器,直接利用Mac里安装的Python编译的,报出如下错误:

urllib2.HTTPError: HTTP Error 403: Forbidden

嗯~果然没错,csdn是反感爬虫的,可是我只是想方便的知道我的访问量和评论数嘛...

于是采用博客里的3.3方法,把urllib2伪装成浏览器访问,我的代码就变成了这样:

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">import urllib2  
  2.   
  3. headers = {  
  4.     'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'  
  5. }  
  6. req = urllib2.Request(  
  7.     url = 'http://blog.csdn.net/yuri_4_vera',  
  8.     headers = headers  
  9. )  
  10.   
  11. content = urllib2.urlopen(req).read()  
  12. print content  





成功的抓下来我的整个博客主页有木有!print输出的全是HTML的代码有木有!看到哗啦啦的代码刷下去太舒服了..
学校课程真紧..操作系统、数据挖掘两个大实验..今儿就到这儿吧。
就不附上主页的代码了,如果用Chrome的话,可以右键审查元素。Safari的话可以在偏好设置里勾选“在菜单栏里显示开发菜单”,就可以右键检查元素了。


主要是需要这一部分的内容:

 

 

[html] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. <span style="font-size:18px;"><ul id="blog_rank">  
  2.     <li>访问:<span>308次span>li>  
  3.     <li>积分:<span>41分span>li>  
  4.     <li>排名:<span>千里之外span>li>  
  5. ul>  
  6. <ul id="blog_statistics">  
  7.     <li>原创:<span>4篇span>li>  
  8.     <li>转载:<span>0篇span>li>  
  9.     <li>译文:<span>0篇span>li>  
  10.     <li>评论:<span>1条span>li>  
  11. ul>span>  


 

2013.11.5_抓到了!

抓到了!先看看抓到的东西长什么样:

开发记录_自学Python写爬虫程序爬取csdn个人博客信息

 

最底下的部分就是抓出来的。

 

昨天已经抓到了整个主页,今天主要是想办法把需要用的这部分内容挑出来。

昨晚上简单查了下,据说需要使用正则表达式,听到这个名字只觉得耳熟不觉得有数...

问了问同学,发觉似乎是离散数学还是什么课里讲过的一个部分……上课不听课的默默去谷歌了..

到了中午回来,还是不知道要怎么具体操作,后来在Ubuntu中文搜到这样一篇文章

Python正则表达式操作指南

其中有这么一个部分 4.4 前向界定符

 

受益匪浅!

尝试了一下

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">result = re.findall(r'(?<=\).+?(?=\<\/ul\>)',content)  


很显然..出错了。

 

Python的转义字符还是不太懂的样子..

后来尝试

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">result = re.findall(r'(?<=).+?(?=\)',content)  


只能筛选出来“[]”,很奇怪……

 

后来就随便一试,发现了

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. "font-size:18px;">result = re.findall(r'(?<=
  2. ).+?(?=
  3. )',content)  


成功的抓出了我需要的部分!

 

 

[html] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. <span style="font-size:18px;">访问:<span>308次span>  
  2. 积分:<span>41分span>  
  3. 排名:<span>千里之外span>  
  4. 原创:<span>4篇span>  
  5. 转载:<span>0篇span>  
  6. 译文:<span>0篇span>  
  7. 评论:<span>1条span>span>  


热泪盈眶……

 

 

 

完结!


附上代码:

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
  1. import urllib2  
  2. import re  
  3.   
  4. headers = {  
  5.     'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'  
  6. }  
  7. req = urllib2.Request(  
  8.     url = 'http://blog.csdn.net/yuri_4_vera',  
  9.     headers = headers  
  10. )  
  11.   
  12. content = urllib2.urlopen(req).read()  
  13. result = re.findall(r'(?<=
  14. ).+?(?=
  15. )',content)  
  16.   
  17. for x in xrange(0,7):  
  18.     print result[x]  
  19.     pass  



最近忙别的事情,这里再加一句替换,就可以把烦人的去掉,用php抓的那篇博文里我有加,python最近还没空继续钻...

 

/************2013-12-3**************/

更新:

感谢@laochx的反馈,对于编码问题的解决,可以添加以下代码:

 

 

[python] view plaincopyprint?开发记录_自学Python写爬虫程序爬取csdn个人博客信息开发记录_自学Python写爬虫程序爬取csdn个人博客信息
 
    1. content = urllib2.urlopen(req).read()  
    2. cOntent=content.decode("utf8")  
    3. result = re.findall(r'(?<=
    4. ).+?(?=
    5. )',content)  

推荐阅读
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • 360SRC安全应急响应:从漏洞提交到修复的全过程
    本文详细介绍了360SRC平台处理一起关键安全事件的过程,涵盖从漏洞提交、验证、排查到最终修复的各个环节。通过这一案例,展示了360在安全应急响应方面的专业能力和严谨态度。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • 本文介绍如何使用 Python 提取和替换 .docx 文件中的图片。.docx 文件本质上是压缩文件,通过解压可以访问其中的图片资源。此外,我们还将探讨使用第三方库 docx 的方法来简化这一过程。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 本文详细记录了在银河麒麟操作系统和龙芯架构上使用 Qt 5.15.2 进行项目打包时遇到的问题及解决方案,特别关注于 linuxdeployqt 工具的应用。 ... [详细]
  • 本文深入探讨了C++对象模型中的一些细节问题,特别是虚拟继承和析构函数的处理。通过具体代码示例和详细分析,揭示了书中某些观点的不足之处,并提供了更合理的解释。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • libsodium 1.0.15 发布:引入重大不兼容更新
    最新发布的 libsodium 1.0.15 版本带来了若干不兼容的变更,其中包括默认密码散列算法的更改和其他重要调整。 ... [详细]
  • 本文介绍如何在Java项目中使用Log4j库进行日志记录。我们将详细说明Log4j库的引入、配置及简单应用,帮助开发者快速上手。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有