首页 > 编程 > Python > 正文

01_python爬虫_五种方法通过黑板客第一关

2019-11-06 08:03:06
字体:
来源:转载
供稿:网友

在网上找到了一个练习爬虫的网站,挺有意思的,第一关网址: http://www.heibanke.com/lesson/crawler_ex00/

页面如下:

第一关的规则就是 在网址后面输入数字,

然后打开下一个页面,之后重复如此,直到通关为止,

因此手动的输入有些繁琐,就需要用爬虫来完成

第一种方法

使用urllib和正则表达式

#!/usr/bin/python# coding:utf-8#注意事项:在linux平台上,前面两句注释是这样写的,尤其是第一句没有空格。#本程序是用于python爬虫练习,用于在黑板客上闯关所用。#程序分析:打开黑板客首页:http://www.heibanke.com/lesson/crawler_ex00/#发现第一关就是让你不停的更换域名,然后打开新的网页# 那思路如下:# 1.网页打开模块# 2.在打开的网页中通过bs4或者正则表达式获取网页中的数字串,然后组成新的网页地址再次打开,然后一直重复。import reimport urllibimport datetimebegin_time=datetime.datetime.now()url = 'http://www.heibanke.com/lesson/crawler_ex00/'html = urllib.urlopen(url).read()index=re.findall(r'输入数字([0-9]{5})',html)while index:	url='http://www.heibanke.com/lesson/crawler_ex00/%s/' % index[0]	PRint url	html=urllib.urlopen(url) .read() 	index=re.findall(r'数字是([0-9]{5})',html)html=urllib.urlopen(url).read() url='http://www.heibanke.com'+re.findall(r'<a href="(.*?)" class',html )[0]print '最后通关的的网址是%s, 耗时%s' % (url,(datetime.datetime.now()-begin_time))print 'just for test,是吧!

最终结果如下:

>>> http://www.heibanke.com/lesson/crawler_ex00/64899/http://www.heibanke.com/lesson/crawler_ex00/36702/http://www.heibanke.com/lesson/crawler_ex00/83105/http://www.heibanke.com/lesson/crawler_ex00/25338/http://www.heibanke.com/lesson/crawler_ex00/19016/http://www.heibanke.com/lesson/crawler_ex00/13579/http://www.heibanke.com/lesson/crawler_ex00/43396/http://www.heibanke.com/lesson/crawler_ex00/39642/http://www.heibanke.com/lesson/crawler_ex00/96911/http://www.heibanke.com/lesson/crawler_ex00/30965/http://www.heibanke.com/lesson/crawler_ex00/67917/http://www.heibanke.com/lesson/crawler_ex00/22213/http://www.heibanke.com/lesson/crawler_ex00/72586/http://www.heibanke.com/lesson/crawler_ex00/48151/http://www.heibanke.com/lesson/crawler_ex00/53639/http://www.heibanke.com/lesson/crawler_ex00/10963/http://www.heibanke.com/lesson/crawler_ex00/65392/http://www.heibanke.com/lesson/crawler_ex00/36133/http://www.heibanke.com/lesson/crawler_ex00/72324/http://www.heibanke.com/lesson/crawler_ex00/57633/http://www.heibanke.com/lesson/crawler_ex00/91251/http://www.heibanke.com/lesson/crawler_ex00/87016/http://www.heibanke.com/lesson/crawler_ex00/77055/http://www.heibanke.com/lesson/crawler_ex00/30366/http://www.heibanke.com/lesson/crawler_ex00/83679/http://www.heibanke.com/lesson/crawler_ex00/31388/http://www.heibanke.com/lesson/crawler_ex00/99446/http://www.heibanke.com/lesson/crawler_ex00/69428/http://www.heibanke.com/lesson/crawler_ex00/34798/http://www.heibanke.com/lesson/crawler_ex00/16780/http://www.heibanke.com/lesson/crawler_ex00/36499/http://www.heibanke.com/lesson/crawler_ex00/21070/http://www.heibanke.com/lesson/crawler_ex00/96749/http://www.heibanke.com/lesson/crawler_ex00/71822/http://www.heibanke.com/lesson/crawler_ex00/48739/http://www.heibanke.com/lesson/crawler_ex00/62816/http://www.heibanke.com/lesson/crawler_ex00/80182/http://www.heibanke.com/lesson/crawler_ex00/68171/http://www.heibanke.com/lesson/crawler_ex00/45458/http://www.heibanke.com/lesson/crawler_ex00/56056/http://www.heibanke.com/lesson/crawler_ex00/87450/http://www.heibanke.com/lesson/crawler_ex00/52695/http://www.heibanke.com/lesson/crawler_ex00/36675/http://www.heibanke.com/lesson/crawler_ex00/25997/http://www.heibanke.com/lesson/crawler_ex00/73222/http://www.heibanke.com/lesson/crawler_ex00/93891/http://www.heibanke.com/lesson/crawler_ex00/29052/http://www.heibanke.com/lesson/crawler_ex00/72996/http://www.heibanke.com/lesson/crawler_ex00/73999/http://www.heibanke.com/lesson/crawler_ex00/23814/最后通关的的网址是http://www.heibanke.com/lesson/crawler_ex01/, 耗时0:00:49.396000just for test,是吧!>>>

第二种方法

使用request 和 re  模块配合
#!/usr/bin/python# coding:utf-8#通过urllib 的方法获取网页内容,通过正则表达式获取所需的字符import requestsimport reimport datetime,sysreload(sys)sys.setdefaultencoding('utf-8')begin_time=datetime.datetime.now()url = r'http://www.heibanke.com/lesson/crawler_ex00/'new_url = urlnum_re = re.compile(r'<h3>[^/d<]*?(/d+)[^/d<]*?</h3')while True:	print '正在读取网址 ',new_url	html = requests.get(new_url).text	num = num_re.findall(html)	if len(num) == 0:		new_url='http://www.heibanke.com'+re.findall(r'<a href="(.*?)" class',html )[0]		break;	else:		new_url = url+num[0]print '最后通关的的网址是%s, 耗时%s' % (new_url,(datetime.datetime.now()-begin_time))print 'just for 测试!最终耗时为:
最后通关的的网址是http://www.heibanke.com/lesson/crawler_ex01/, 耗时0:01:37.520779just for 测试!这里还有一种正则匹配方式,可以借鉴一下
pattern = r'<h3>(.*)</h3>'result = re.findall(pattern, content)try:	num = int(''.join(map(lambda n: n if n.isdigit() else '', result[0])))except:	break这里涉及到了几个函数:join()函数map()函数以及lambda的使用

join()函数

其实就是一个拼接函数,看下面的几个例子
>>> st1=['hello','world','','','j','i','m']#以空字符串来进行分割,其实就是直接将list 里面的元素重新连接在了一起>>> ''.join(st1)'helloworldjim'#以 ‘.’ 小数点来进行连接, 这样,原本是空字符的元素也要占用相应的位置 >>> '.'.join(st1)'hello.world...j.i.m'#同样的道理,针对字符串也适用>>> st2='this is sendy'>>> ''.join(st2)'this is sendy'>>> ':'.join(st2)'t:h:i:s: :i:s: :s:e:n:d:y'>>>join()函数语法:'sep'.join(seq)参数说明sep:分隔符。可以为空seq:要连接的元素序列、字符串、元组、字典上面的语法即:以sep作为分隔符,将seq所有的元素合并成一个新的字符串返回值:返回一个以分隔符sep连接各个元素后生成的字符串

map()函数

 传入的list的每一个元素进行映射,返回一个新的映射之后的list
def format_name(s):    s1=s[0:1].upper()+s[1:].lower();    return s1;print map(format_name, ['adam', 'LISA', 'barT'])输入:['adam', 'LISA', 'barT']输出:['Adam', 'Lisa', 'Bart']map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

lambda的使用

它的作用类似于def 语句, 即用关键字 lambda来简写一个函数
>>> aa=lambda : True if 4>6 else False>>> aa()False>>> aa = lambda sr1:sr1+1>>> aa(5)6lambda存在意义就是对简单函数的简洁表示

第三种方法

通过urllib2 和re 库来实现
#!/usr/bin/python# coding:utf-8#通过urllib2 的方法打开网页,获取网页内容,网页里面的内容则通过正则表达式来匹配import reimport urllib2import datetime  begin_time=datetime.datetime.now()url = 'http://www.heibanke.com/lesson/crawler_ex00/'html = urllib2.urlopen(url).read()index=re.findall(r'输入数字([0-9]{5})',html)while index:	url='http://www.heibanke.com/lesson/crawler_ex00/%s/' % index[0]	print url	html=urllib2.urlopen(url) .read() 	index=re.findall(r'数字是([0-9]{5})',html)html=urllib2.urlopen(url).read() url='http://www.heibanke.com'+re.findall(r'<a href="(.*?)" class',html )[0]print '最后通关的的网址是%s, 耗时%s' % (url,(datetime.datetime.now()-begin_time))最终耗时:
最后通关的的网址是http://www.heibanke.com/lesson/crawler_ex01/, 耗时0:00:42.172931

第四种方法

使用urllib2,re和BeautifulSoup库来实现
#!/usr/bin/python# coding:utf-8#这个方法使用 bs4 即beautiful 获取有用的信息,然后将获取到的数据通过正则表达式进行处理import reimport urllib2import datetimefrom bs4 import BeautifulSoupbegin_time=datetime.datetime.now()url = 'http://www.heibanke.com/lesson/crawler_ex00/'  url2=urlwhile True:	print '正在爬取',url2	html = urllib2.urlopen(url2).read()	soup = BeautifulSoup(html,'html.parser',from_encoding='utf8')	str1=soup.find_all('h3') #获取信息内容	str2= (''.join(str1[0])) #通过这种处理得到字符串	str3=re.findall(r'[/d]{5}',str2)#通过正则表达式得到数字	if len(str3) == 0:#对数字长度进行判断,可以在最后跳出循环		new_url='http://www.heibanke.com'+re.findall(r'<a href="(.*?)" class',html )[0]		break;	else:		url2=url+str3[0]#对url进行重组,可以获得下一个urlprint '最后通关的的网址是%s, 耗时%s' % (url,(datetime.datetime.now()-begin_time))最终耗时:
最后通关的的网址是http://www.heibanke.com/lesson/crawler_ex00/, 耗时0:00:43.508280

第五种方法

使用 webdriver与re 正则表达式配合
#!/usr/bin/python# coding:utf-8#这个方法使用 webdriver获取页面内容 ,然后将获取到的数据通过正则表达式进行处理import reimport datetimefrom selenium import webdriverimport sysreload(sys)sys.setdefaultencoding('utf-8')begin_time=datetime.datetime.now()url = 'http://www.heibanke.com/lesson/crawler_ex00/'  driver=webdriver.PhantomJS()driver.get(url)content= driver.find_element_by_tag_name('h3').textprint contentcontent=re.findall('([0-9]{5})',content)while True:	if len(content) == 0:#对数字长度进行判断,可以在最后跳出循环		content= driver.find_element_by_xpath('/html/body/div/div/div[2]/a')		url=content.get_attribute('href')		break;	else:		url='http://www.heibanke.com/lesson/crawler_ex00/%s' % content[0] #对url进行重组,可以获得下一个url		driver.get(url)		content= driver.find_element_by_tag_name('h3').text		print content		content=re.findall('([0-9]{5})',content)print '最后通关的的网址是%s, 耗时%s' % (url,(datetime.datetime.now()-begin_time))driver.quit()耗时:
恭喜你,你找到了答案.继续你的爬虫之旅吧最后通关的的网址是http://www.heibanke.com/lesson/crawler_ex01/, 耗时0:02:07.484190

小技巧

这里面有个小技巧,可以获取程序运行的时间:
datetime.datetime.now()在程序开始和结束的时候都执行一下这一句,然后将结果相减就获得了程序运行的时间。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表