python爬虫(3)五种方法通过黑板客第一关
在网上找到了一个练习爬虫的网站,挺有意思的,第一关网址: http://www.heibanke.com/lesson/crawler_ex00/
页面如下:
第一关的规则就是 在网址后面输入数字,
然后打开下一个页面,之后重复如此,直到通关为止,
因此手动的输入有些繁琐,就需要用爬虫来完成
第一种方法
使用urllib和正则表达式
# coding:utf-8
#注意事项:在linux平台上,前面两句注释是这样写的,尤其是第一句没有空格。
#本程序是用于python爬虫练习,用于在黑板客上闯关所用。
#程序分析:打开黑板客首页:http://www.heibanke.com/lesson/crawler_ex00/
#发现第一关就是让你不停的更换域名,然后打开新的网页
# 那思路如下:
# 1.网页打开模块
# 2.在打开的网页中通过bs4或者正则表达式获取网页中的数字串,然后组成新的网页地址再次打开,然后一直重复。
import re
import urllib
import datetime
begin_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.396000
just for test,是吧!
第二种方法
使用request 和 re 模块配合
#!/usr/bin/python
# coding:utf-8
#通过urllib 的方法获取网页内容,通过正则表达式获取所需的字符
import requests
import re
import datetime,sys
reload(sys)
sys.setdefaultencoding('utf-8')
begin_time=datetime.datetime.now()
url = r'http://www.heibanke.com/lesson/crawler_ex00/'
new_url = url
num_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))
最终耗时为:
最后通关的的网址是http://www.heibanke.com/lesson/crawler_ex01/, 耗时0:01:37.520779
这里还有一种正则匹配方式,可以借鉴一下
这里涉及到了几个函数:
join()函数
map()函数
以及lambda的使用
语法:'sep'.join(seq)
参数说明
sep:分隔符。可以为空
seq:要连接的元素序列、字符串、元组、字典
上面的语法即:以sep作为分隔符,将seq所有的元素合并成一个新的字符串
返回值:返回一个以分隔符sep连接各个元素后生成的字符串
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)
6
lambda存在意义就是对简单函数的简洁表示
第三种方法
通过urllib2 和re 库来实现
#!/usr/bin/python
# coding:utf-8
#通过urllib2 的方法打开网页,获取网页内容,网页里面的内容则通过正则表达式来匹配
import re
import urllib2
import 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 re
import urllib2
import datetime
from bs4 import BeautifulSoup
begin_time=datetime.datetime.now()
url = 'http://www.heibanke.com/lesson/crawler_ex00/'
url2=url
while 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进行重组,可以获得下一个url
print '最后通关的的网址是%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 re
import datetime
from selenium import webdriver
import sys
reload(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').text
print content
content=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()
在程序开始和结束的时候都执行一下这一句,然后将结果相减就获得了程序运行的时间。
Tips:
安装BeautifulSoup的方法:
pip install bs4
安装selenium
pip install selenium
另外需要在网上下载 PhantomJS