在网上找到了一个练习爬虫的网站,挺有意思的,第一关网址: 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的每一个元素进行映射,返回一个新的映射之后的listdef 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()在程序开始和结束的时候都执行一下这一句,然后将结果相减就获得了程序运行的时间。
新闻热点
疑难解答