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

于是萌生了一个想法:

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

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

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

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

2013.11.3_开工

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

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

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

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

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

  1. <span style="font-size:18px;">import urllib, urllister
  2. def getURL(url):
  3. try:
  4. usock = urllib.urlopen(url)
  5. except:
  6. print 'get url excepton'
  7. return []
  8. parser = urllister.URLLister()
  9. parser.feed(usock.read())
  10. usock.close()
  11. parser.close()
  12. urls = parser.urls
  13. return urls</span>

对于函数的定义,只要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.最基本的抓站

  1. <span style="font-size:18px;">import urllib2
  2. content = urllib2.urlopen('http://XXXX').read()</span>

2.使用代理服务器

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

  1. <span style="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()</span>

3.需要登录的情况

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

3.1 cookie的处理

  1. <span style="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()</span>

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

  1. <span style="font-size:18px;">opener = urllib2.build_opener(proxy_support, cookie_support, urllib2.HTTPHandler)</span>

3.2 表单的处理

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

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

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

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

-

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

  1. <span style="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. })</span>

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

  1. <span style="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()</span>

3.3 伪装成浏览器访问

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

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

  1. <span style="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. )</span>

3.4 反”反盗链”

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

  1. <span style="font-size:18px;">#...
  2. headers = {
  3. 'Referer':'http://www.cnbeta.com/articles'
  4. }
  5. #...</span>

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,但是可以看出是并发地。

  1. <span style="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()</span>

5.验证码的处理

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

1.google那种验证码,

凉拌

2.简单的验证码:

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

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

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

6.总结

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

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

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

  1. <span style="font-size:18px;">import urllib2
  2. content = urllib2.urlopen('http://blog.csdn.net/yuri_4_vera').read()</span>

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

urllib2.HTTPError: HTTP Error 403: Forbidden

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

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

  1. <span style="font-size:18px;">import urllib2
  2. headers = {
  3. 'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
  4. }
  5. req = urllib2.Request(
  6. url = 'http://blog.csdn.net/yuri_4_vera',
  7. headers = headers
  8. )
  9. content = urllib2.urlopen(req).read()
  10. print content</span>

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

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

  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_抓到了!

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

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

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

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

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

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

Python正则表达式操作指南

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

受益匪浅!

尝试了一下

  1. <span style="font-size:18px;">result = re.findall(r'(?<=\<ul id=\"blog\_rank\"\>).+?(?=\<\/ul\>)',content)</span>

很显然..出错了。

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

后来尝试

  1. <span style="font-size:18px;">result = re.findall(r'(?<=<ul id="blog_rank">).+?(?=\</ul>)',content)</span>

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

后来就随便一试,发现了

  1. <span style="font-size:18px;">result = re.findall(r'(?<=<li>).+?(?=</li>)',content)</span>

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

  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>

热泪盈眶……

完结!

附上代码:

  1. import urllib2
  2. import re
  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. content = urllib2.urlopen(req).read()
  11. result = re.findall(r'(?<=<li>).+?(?=</li>)',content)
  12. for x in xrange(0,7):
  13. print result[x]
  14. pass

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

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

更新:

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

    1. content = urllib2.urlopen(req).read()
    2. content=content.decode("utf8")
    3. result = re.findall(r'(?<=<li>).+?(?=</li>)',content)

开发记录_自学Python写爬虫程序爬取csdn个人博客信息的更多相关文章

  1. python网络爬虫--简单爬取糗事百科

    刚开始学习python爬虫,写了一个简单python程序爬取糗事百科. 具体步骤是这样的:首先查看糗事百科的url:http://www.qiushibaike.com/8hr/page/2/?s=4 ...

  2. 利用python的爬虫技术爬取百度贴吧的帖子

    在爬取糗事百科的段子后,我又在知乎上找了一个爬取百度贴吧帖子的实例,为了巩固提升已掌握的爬虫知识,于是我打算自己也做一个. 实现目标:1,爬取楼主所发的帖子 2,显示所爬去的楼层以及帖子题目 3,将爬 ...

  3. python网络爬虫《爬取get请求的页面数据》

    一.urllib库 urllib是python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在python3中的为urllib.request和urllib. ...

  4. Python学习 —— 爬虫入门 - 爬取Pixiv每日排行中的图片

    更新于 2019-01-30 16:30:55 我另外写了一个面向 pixiv 的库:pixiver 支持通过作品 ID 获取相关信息.下载等,支持通过日期浏览各种排行榜(包括R-18),支持通过 p ...

  5. 初识python 之 爬虫:爬取某网站的壁纸图片

    用到的主要知识点:requests.get 获取网页HTMLetree.HTML 使用lxml解析器解析网页xpath 使用xpath获取网页标签信息.图片地址request.urlretrieve ...

  6. Python网络爬虫 | Scrapy爬取妹子图网站全站照片

    根据现有的知识,写了一个下载妹子图(meizitu.com)Scrapy脚本,把全站两万多张照片下载到了本地. 网站的分析 网页的网址分析 打开网站,发现网页的网址都是以 http://www.mei ...

  7. python简单爬虫(爬取pornhub特定关键词的items图片集)

    请提前搭好梯子,如果没有梯子的话直接403. 1.所用到的包 requests: 和服务器建立连接,请求和接收数据(当然也可以用其他的包,socket之类的,不过requests是最简单好用的) Be ...

  8. python之爬虫(爬取.ts文件并将其合并为.MP4文件——以及一些异常的注意事项)

    //20200115 最近在看“咱们裸熊——we bears”第一季和第三季都看完了,单单就第二季死活找不到,只有腾讯有资源,但是要vip……而且还是国语版……所以就瞄上了一个视频网站——可以在线观看 ...

  9. 初识python 之 爬虫:爬取双色球中奖号码信息

    人生还是要有梦想的,毕竟还有python.比如,通过python来搞一搞彩票(双色球).注:此文仅用于python学习,结果仅作参考.用到知识点:1.爬取网页基础数据2.将数据写入excel文件3.将 ...

随机推荐

  1. SQL Server索引进阶:第七级,过滤的索引

    原文地址: Stairway to SQL Server Indexes: Level 7,Filtered Indexes 本文是SQL Server索引进阶系列(Stairway to SQL S ...

  2. BootStrap 智能表单系列 九 表单图片上传的支持

    本章介绍如何在生成表单后,可以支持上传图片后可以及时预览图片 代码如下(连接地址:https://github.com/xiexingen/Bootstrap-SmartForm/blob/maste ...

  3. slf4j+log4j配置(Maven)

    首先配置Maven依赖 <!-- http://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 --> <dependency& ...

  4. SignaLR通信技术

    新建MVC项目 如果没有Signale需要使用NuGet安装Signalr namespace SignaLrDemo { public class ChatHub : Hub { public vo ...

  5. hdu1114小猪抢劫银行

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1114 完全背包 题意:给出小猪钱罐的重量和装满钱后的重量,然后是几组数据,每组数据包括每种钱币的价值与重量 ...

  6. Linux C 简易聊天室

    Linux下实现聊天室 介绍:程序在CentOS下,采用C语言实现,结构为Client/Server结构; 服务端程序通过共享存储区存储聊天数据,并发送给每个连接的客户端: 服务端程序和客户端程序都是 ...

  7. 闲来无事写写-Huffman树的生成过程

    前言:最近项目上一直没事干,感觉无聊到了极点,给自己找点事做,补一下大学没有完成的事情,写一个huffman算法Java版的,学校里面写过c语言的. 因为很久没搞数据结构和算法这方面了(现在搞Java ...

  8. 阿里云ECS每天一件事D1:配置SSH

    近期因为项目需求,采购了两台阿里云ECS,选择的系统为CentOS 6.3 X64 安全加固版,额外买了160G的硬盘,应该够应付此项目的需求了. ECS默认已经配置好了sshd服务,可以使用root ...

  9. cpu卡,sam卡原理

    第一部分 CPU基础知识一.为什么用CPU卡IC卡从接口方式上分,可以分为接触式IC卡.非接触式IC卡及复合卡.从器件技术上分,可分为非加密存储卡.加密存储卡及CPU卡.非加密卡没有安全性,可以任意改 ...

  10. 定位CPU高的方法

    CPU占用高,最常见的原因是死循环或者类死循环的操作,如果要逐一排查代码,费时费力,可以先用工具 工具1.windbg,windows出品的牛刀一枚以管理员运行windbg,File->Atta ...