Python之原生爬虫(十)
一.爬虫实例
1.原理:文本分析并提取信息——正则表达式。
2.实例目的:爬取熊猫TV某个分类下面主播的人气排行
分析网站结构
操作:F12查看HTML信息,Ctrl+Shift+C鼠标选取后找到对应的HTML。
3.步骤:
前奏:
1、明确目的(分析抓取目的确定抓取页面)
2、找到数据对应网页
3、分析网页的结构,找到数据所在标签的位置
执行:
4、模拟HTTP请求,向服务器发送请求,获取到服务器返回给我们的HTML
5、用正则表达式提取我们要的数据
......
4.代码
二. VSCode中调试代码
断点调试:F5启动,F10单步,F5跳断点,F11进内部
三.HTML结构分析基本原则
寻找到标签、标识符,使之能够定位要抓取的信息。
1、尽量选取具有唯一性的标签
2、尽量选取最接近于数据的标签
四.数据提取层级分析及原则
1.可以把两个数据看成是一组数据并再次寻找标签。
2.尽量选取可以闭合的标签(父级标签),并包裹其需要的数据。
五.正则分析HTML及具体流程
1.对于最外层的标签做法
把中间内容用圆括号括起来,用组来去掉两边的定界字符。
root_pattern = '<div class="video-info">([\s\S]*?)</div>'
2.正则分析获取名字和人数
name_pattern = '</i>([\s\S]*?)</span>'
number_pattern = '<span class="video-number">([\s\S]*?)</span>'
3.数据精炼
去除字符串中的空格等:strip()
def __refine(self,anchors):
l = lambda anchor:{
'name':anchor['name'][0].strip(),
'number':anchor['number'][0] #列表转化为单一的字符串
}
return map(1,anchors)
4.sorted 排序(业务处理)
def __sort_seed(self,anchor):
r = re.findall('\d*',anchor['number']) #提取数字
number = float(r[0]) #把文本转换成数字
if '万' in anchor['number']: #处理'万'
number *= 10000
return number
def __sort(self,anchors):
anchors = sorted(anchors,key = self.__sort_seed,reverse = True)
#key确定比较对象
#sorted()默认升序排列,reverse = True 降序
#不能用str排序,要用int,并且要处理'万'
return anchors
5.案例总结
快捷键:ctrl+shift+O:查找函数名
'''
This is a spider,模块注释
'''
from urllib import request
import re
class Spider():
'''
This is a spider class
'''
url = 'https://www.panda.tv/cate/lol'
root_pattern = '<div class="video-info">([\s\S]*?)</div>' #注意单双引号
#[\w\W] [\s\S] . 匹配所有字符
#* 匹配0次或者无限多次
#? 非贪婪模式,匹配到第一个遇到的</div>
name_pattern = '</i>([\s\S]*?)</span>'
number_pattern = '<span class="video-number">([\s\S]*?)</span>'
def __fetch_content(self):
'''
私有方法,获取网页内容
'''
r = request.urlopen(Spider.url)
htmls = r.read()
htmls = str(htmls,encoding = 'utf-8')
return htmls
def __analysis(self,htmls):
'''
正则表达式来提取数据
'''
root_html = re.findall(Spider.root_pattern,htmls)
anchors = []
for html in root_html:
name = re.findall(Spider.name_pattern,html)
number = re.findall(Spider.number_pattern,html)
anchor = {'name':name,'number':number}
anchors.append(anchor)
return anchors
def __refine(self,anchors):
l = lambda anchor:{
'name':anchor['name'][0].strip(),
'number':anchor['number'][0] #列表转化为单一的字符串
}
return map(l,anchors)
def __sort_seed(self,anchor):
r = re.findall('\d*',anchor['number']) #提取数字
number = float(r[0])
if '万' in anchor['number']: #处理'万'
number *= 10000
return number
def __sort(self,anchors):
'''
key确定比较对象
sorted()默认升序排列,reverse = True 降序
不能用str排序,要用int,并且要处理'万'
'''
anchors = sorted(anchors,key = self.__sort_seed,reverse = True)
return anchors
def __show(self,anchors):
for rank in range(0,len(anchors)):
print('rank ' + str(rank + 1) +
':' + ' ' + anchors[rank]['name'] +
'————' + anchors[rank]['number'])
def go(self): #Spider的入口方法
htmls = self.__fetch_content()
anchors = self.__analysis(htmls)
anchors = list(self.__refine(anchors))
anchors = self.__sort(anchors)
self.__show(anchors)
spider = Spider()
spider.go()
爬虫框架:
Beautiful Soup
Scrapy