每天刷开csdn的博客,看到一整个页面,其实对我而言,我只想看看访问量有没有上涨而已...
于是萌生了一个想法:
想写一个爬虫程序把csdn博客上边的访问量和评论数都爬下来。
打算通过网络各种搜集资料,自学写Python代码。
这次自学的历程,也打算及时的整理下来,发布在博客里。
/******************这是程序员风格的分割线******************/
据说Python并不难,看过了python的代码之后也觉得确实,
代码很清爽,相比起C/C++,JS,PHP来讲,python的代码看起来就是舒服。
看了几段别人的爬虫程序教程,还不太清楚Python的编译器是怎么处理代码的。
每一句代码的分割似乎是通过换行,
像是if/else这样的多个语句在一起的,也没有看到大括号,而是像这样:
import urllib, urllister
def getURL(url):
try:
usock = urllib.urlopen(url)
except:
print 'get url excepton'
return []
parser = urllister.URLLister()
parser.feed(usock.read())
usock.close()
parser.close()
urls = parser.urls
return urls
变量的申明只需要在用的时候起个名字就好了,不用规定int, char, float....
我是一个从C语言转学来的乡下孩子..这么高端洋气上档次的定义方式真是惊了个呆。
于是瞬间对Python好感倍增。
看了很多人的爬虫教程,以及代码,还是没什么思路,今天没空了,等明天上手试试看。
不错不错,今天试了试网上的教程,成功的把我的博客主页抓下来了。
中间还遇上些坎坷,不过先感谢一下
月语凋凌 在他的百度空间 Endless Road 里转载的博客
用python爬虫抓站的一些技巧总结
据月语凋凌所说转自 http://gae-django-cms.appspot.com 不过我这里似乎打不开这个网页..
这篇文章真心的帮到了大忙,虽然小小吐槽一下排版不好..
在这里系统的学到了Python爬虫的入门部分。
这位博主请不要介意,我在这里帮你整理一下缩进,再整理一下代码方便大家吧~
<--注意:一直到下一个此类似标记前的内容,均转自月语凋凌 的博客用python爬虫抓站的一些技巧总结,我只是做了整理-->
原文转自http://gae-django-cms.appspot.com/
这些脚本有一个共性,都是和web相关的,总要用到获取链接的一些方法,再加上simplecd这 个半爬虫半网站的项目,
累积不少爬虫抓站的经验,在此总结一下,那么以后做东西也就不用重复劳动了。
import urllib2
content = urllib2.urlopen('http://XXXX').read()
import urllib2
proxy_support = urllib2.ProxyHandler({'http':'http://XX.XX.XX.XX:XXXX'})
opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)
content = urllib2.urlopen('http://XXXX').read()
3.1 cookie的处理
import urllib2, cookielib cookie_support= urllib2.HTTPCookieProcessor(cookielib.CookieJar()) opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler) urllib2.install_opener(opener) content = urllib2.urlopen('http://XXXX').read()
是的没错,如果想同时用代理和cookie,那就加入proxy_support然后operner改为
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
import urllib postdata=urllib.urlencode({ 'username':'XXXXX', 'password':'XXXXX', 'continueURI':'http://www.verycd.com/', 'fk':fk, 'login_submit':'登录' })
然后生成http请求,再发送请求:
req = urllib2.Request( url = 'http://secure.verycd.com/signin/*/http://www.verycd.com/', data = postdata) result = urllib2.urlopen(req).read()
3.3 伪装成浏览器访问
某些网站反感爬虫的到访,于是对爬虫一律拒绝请求
这时候我们需要伪装成浏览器,这可以通过修改http包中的header来实现
headers = { 'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6' } req = urllib2.Request( url = 'http://secure.verycd.com/signin/*/http://www.verycd.com/', data = postdata, headers = headers )
3.4 反”反盗链”
某些站点有所谓的反盗链设置,其实说穿了很简单,就是检查你发送请求的header里面,referer站点是不是他自己,所以我们只需要像3.3一样, 把headers的referer改成该网站即可,以黑幕著称地cnbeta为例:
#... headers = { 'Referer':'http://www.cnbeta.com/articles' } #...
headers是一个dict数据结构,你可以放入任何想要的header,来做一些伪装。例如,有些自作聪明的网站总喜欢窥人隐私,别人通过代理 访问,他偏偏要读取header中的X-Forwarded-For来看看人家的真实IP,没话说,那就直接把X-Forwarde-For改了吧,可以 改成随便什么好玩的东东来欺负欺负他,呵呵。
-
3.5 终极绝招
有时候即使做了3.1-3.4,访问还是会被据,那么没办法,老老实实把httpfox中看到的headers全都写上,那一般也就行了。
再不行,那就只能用终极绝招了,selenium直 接控制浏览器来进行访问,只要浏览器可以做到的,那么它也可以做到。类似的还有pamie,watir,等等等等。
-
from threading import Thread
from Queue import Queue
from time import sleep
#q是任务队列
#NUM是并发线程总数
#JOBS是有多少任务
q = Queue()
NUM = 2
JOBS = 10
#具体的处理函数,负责处理单个任务
def do_somthing_using(arguments):
print arguments
#这个是工作进程,负责不断从队列取数据并处理
def working():
while True:
arguments = q.get()
do_somthing_using(arguments)
sleep(1)
q.task_done()
#fork NUM个线程等待队列
for i in range(NUM):
t = Thread(target=working)
t.setDaemon(True)
t.start()
#把JOBS排入队列
for i in range(JOBS):
q.put(i)
#等待所有JOBS完成
q.join()
1.google那种验证码,
凉拌
2.简单的验证码:
字符个数有限,只使用了简单的平移或旋转加噪音而没有扭曲的,这种还是有可能可以处理的,一般思路是旋转的转回来,噪音去掉,然后划分 单个字符,划分好了以后再通过特征提取的方法(例如PCA) 降维并生成特征库,然后把验证码和特征库进行比较。这个比较复杂,一篇博文是说不完的,这里就不展开了,具体做法请弄本相关教科书好好研究一下。
3.事实上有些验证码还是很弱的,
这里就不点名了,反正我通过2的方法提取过准确度非常高的验证码,所以2事实上是可行的。
<--注意:以上内容均转自月语凋凌 的博客用python爬虫抓站的一些技巧总结,我只是做了整理,以下内容为本人原创-->
利用这篇博客里的例子,我先模仿了一个自己的Python爬虫。
import urllib2
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伪装成浏览器访问,我的代码就变成了这样:
import urllib2
headers = {
'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
}
req = urllib2.Request(
url = 'http://blog.csdn.net/yuri_4_vera',
headers = headers
)
content = urllib2.urlopen(req).read()
print content
- 访问:308次
- 积分:41分
- 排名:千里之外
- 原创:4篇
- 转载:0篇
- 译文:0篇
- 评论:1条
抓到了!先看看抓到的东西长什么样:
最底下的部分就是抓出来的。
昨天已经抓到了整个主页,今天主要是想办法把需要用的这部分内容挑出来。
昨晚上简单查了下,据说需要使用正则表达式,听到这个名字只觉得耳熟不觉得有数...
问了问同学,发觉似乎是离散数学还是什么课里讲过的一个部分……上课不听课的默默去谷歌了..
到了中午回来,还是不知道要怎么具体操作,后来在Ubuntu中文搜到这样一篇文章
Python正则表达式操作指南
其中有这么一个部分 4.4 前向界定符
受益匪浅!
尝试了一下
result = re.findall(r'(?<=\).+?(?=\<\/ul\>)',content)
Python的转义字符还是不太懂的样子..
后来尝试
result = re.findall(r'(?<=).+?(?=\
)',content)
后来就随便一试,发现了
result = re.findall(r'(?<=).+?(?= )',content)
访问:308次
积分:41分
排名:千里之外
原创:4篇
转载:0篇
译文:0篇
评论:1条
完结!
附上代码:
import urllib2
import re
headers = {
'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'
}
req = urllib2.Request(
url = 'http://blog.csdn.net/yuri_4_vera',
headers = headers
)
content = urllib2.urlopen(req).read()
result = re.findall(r'(?<=).+?(?= )',content)
for x in xrange(0,7):
print result[x]
pass
/************2013-12-3**************/
更新:
感谢@laochx的反馈,对于编码问题的解决,可以添加以下代码:
content = urllib2.urlopen(req).read()
content=content.decode("utf8")
result = re.findall(r'(?<=).+?(?= )',content)