目标:爬取熊猫TV某个分类下面主播的人气排行
分析网站结构
- 使用Chrome浏览器
- F12查看HTML信息,Ctrl+Shift+C鼠标选取后找到对应的HTML。
- 文本分析并提取信息——正则表达式。
搜索引擎,今日头条等app本质上的技术就是爬虫
设计步骤:
- 明确目的
- 找到数据对应网页
- 分析网页的结构,找到数据所在标签的位置
- 模拟HTTP请求,向服务器发送请求,获取到服务器返回给我们的HTML
- 用正则表达式提取我们要的数据
- 处理数据
HTML结构分析基本原则
1. 寻找到标签、标识符,使之能够定位要抓取的信息
- 尽量选取具有唯一性的标签
- 尽量选取最接近于数据的标签
2. 把多个个数据看成是一组数据并再次寻找标签
- 尽量选取可以闭合的标签(父级标签),并包裹其需要的数据。
提取顺序:htmls->video-info->video-nickname/video-number->提取数据
正则匹配
匹配父级标签
root_pattern = '<div class="video-info">([\s\S]*?)</div>' #此处要使用非贪婪,否则会无限匹配下去。
匹配名字和人数
name_pattern = '</i>([\s\S]*?)</span>'
number_pattern = '<i class="ricon ricon-eye"></i>([\s\S]*?)</span>'
数据精炼
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):
anchors = sorted(anchors,key = self.__sort_seed,reverse = True)
#key确定字典中哪个元素作为比较对象
#sorted()默认升序排列,reverse = True降序
return anchors
VSCode中调试代码
断点调试:F5启动,F10单步,F5跳断点,F11进内部
整体代码:
from urllib import request
import re
class Spider():
url = 'https://www.panda.tv/cate/lol'
root_pattern = '<div class="video-info">([\s\S]*?)</div>'
name_pattern = '</i>([\s\S]*?)</span>'
number_pattern = '<i class="ricon ricon-eye"></i>([\s\S]*?)</span>'
def __fetch_content(self):
r = request.urlopen(Spider.url) #获取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 = []
# print(root_html[0])
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)
# print(anchors[0])
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):
anchors = sorted(anchors,key = self.__sort_seed,reverse = True)
#key确定字典中哪个元素作为比较对象
#sorted()默认升序排列,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):
htmls = self.__fetch_content()
anchors = self.__analysis(htmls)
anchors = list(self.__refine(anchors))
anchors = self.__sort(anchors)
self.__show(anchors)
spider = Spider()
spider.go()
网友评论