完整的爬虫:
反扒机制,自动登录,代理IP等等
复制
示例爬虫:
简单的数据抓取,简单的数据处理
复制
目的:
不使用爬虫框架完成数据爬取
巩固知识、合理编程、内部原理
复制
示例内容:
内容:
爬取直播网站
确定工作:
确定爬取数据:某个分类下各主播人气的数据
确定实现结果:将人气进行排序
准备:
分析网站结构
寻找包含爬取信息的页面
F12检查网页,定位信息(主播姓名,人气数据)
原理:
对html文件进行文本分析并从中提取信息
使用技术
正则表达式
具体步骤:
模拟HTTP请求,向服务器发送请求,获取到服务器返回的HTML
用正则表达式处理网页文本,过滤出有用数据
找到相关常量标签,作为正则的定位边界
定位标签:
尽量选择具有唯一标识的标识的标签
尽量选择与目标数据相近的标签
尽量选择将所有目标数据都包含的标签(闭合的标签),比如包含姓名+人气的标签
上述即尽量选父标签,不选兄弟标签,为了易于构造正则提取内容
注意:
构造正则不是难点,难点是应对反爬虫的措施
整体书写规范
每行代码不要过长
推荐书写一个入口程序
推荐在入口中平行的调用逻辑代码
每个方法中代码尽量少
注意块注释和行级注释的书写格式
代码结构:
复制
'''
类注释
'''
class spider():
#抓取页面内容(行注释)
def __fetch_content(self):
'''
方法注释
'''
pass
#数据抽取
def __analysis(self, htmls):
pass
#数据精炼
def __refine(self, pairs):
pass
#排序
def __sort(self, pairs):
pass
#排序的算子
def __seed(self, pairs):
pass
#数据展现
def __show(self, pairs):
pass
#函数入口
def go(self):
调用
s = spider()
s.go()
```
书写代码:
抓取页面:
url = 'http://www.huya.com/g/lol'
分析原网页:
复制
<li class="game-live-item" gid="1">
<a href="http://www.huya.com/yanmie" class="video-info new-clickstat" target="_blank" report='{"eid":"click/position","position":"lol/0/1/5","game_id":"1","ayyuid":"380335691"}'>
<img class="pic" data-original="//screenshot.msstatic.com/yysnapshot/1711a622dc4d670fe32de2018f78a2d030fcde37cfe8?imageview/4/0/w/338/h/190/blur/1" src="//a.msstatic.com/huya/main/assets/img/default/338x190.jpg" onerror="this.onerror=null; this.src='//a.msstatic.com/huya/main/assets/img/default/338x190.jpg';" alt="最强赵信折翼的直播" title="最强赵信折翼的直播">
<div class="item-mask"></div>
<i class="btn-link__hover_i"></i>
<em class="tag tag-blue">蓝光</em> </a>
<a href="http://www.huya.com/yanmie" class="title new-clickstat" report='{"eid":"click/position","position":"lol/0/1/5","game_id":"1","ayyuid":"380335691"}' title="可以用赵信上王者第一的男人" target="_blank">可以用赵信上王者第一的男人</a>
<span class="txt">
<span class="avatar fl">
<img data-original="//huyaimg.msstatic.com/avatar/1081/63/c83bdc0701b64646c86065e273fd05_180_135.jpg" src="//a.msstatic.com/huya/main/assets/img/default/84x84.jpg" onerror="this.onerror=null; this.src='//a.msstatic.com/huya/main/assets/img/default/84x84.jpg';" alt="最强赵信折翼" title="最强赵信折翼">
<i class="nick" title="最强赵信折翼">最强赵信折翼</i>
</span>
<span class="num"><i class="num-icon"></i><i class="js-num">1.5万</i></span>
</span>
</li>
复制
<span class="txt">
<span class="avatar fl">
<img data-original="//huyaimg.msstatic.com/avatar/1081/63/c83bdc0701b64646c86065e273fd05_180_135.jpg" src="//a.msstatic.com/huya/main/assets/img/default/84x84.jpg" onerror="this.onerror=null; this.src='//a.msstatic.com/huya/main/assets/img/default/84x84.jpg';" alt="最强赵信折翼" title="最强赵信折翼">
<i class="nick" title="最强赵信折翼">最强赵信折翼</i>
</span>
<span class="num"><i class="num-icon"></i><i class="js-num">1.5万</i></span>
</span>
复制
目标数据:
最强赵信折翼,1.5万
构造正则表达式:
选出上面的最小公约子集:
root_pattern = '<span class="txt">([\s\S]*?)\r\n</li>'
注意:
要加问号,声明是非贪婪的匹配
然后选出,姓名:
name_pattern = '<i class="nick" title="([\s\S]*?)">'
然后选出,人气:
num_pattern = '<i class="js-num">([\s\S]*?)</i>'
注意:
上述正则的边界并不一定是完整的html标签,因为使用正则即对字符进行匹配,所以可以随意拆分。
几个重要功能:
获取页面内容:
from urllib import request
tmp = request.urlopen(spider.url)
htmls = tmp.read()
注意:此处的结果是字节码:bytes
必须要进行转化:bytes->str
htmls = str(htmls,encoding='utf-8')
注意:不推荐打印出页面内容,会出现解码问题,可以加断点调试
循环:
此处的循环需要获取到下标,而直接for i in list,获取不到下标
此时应该使用for index in range(0,len(list))这种形式
代码:
for rank in range(0, len(pairs)):
print('第',rank,'名:',pairs[rank]['name'],':',pairs[rank]['number'])
排序:
此处使用内置函数sorted(iterable, cmp=None, key=None, reverse=False)
注意:
key = 函数名,此函数应该返回排序的比较值
cmp = 函数名,此函数可以重写排序规则
reverse=False,从小到大正序排列
代码:
sorted(pairs,key = seed,reverse = True)
def seed(self, pairs):
tmp = pairs['number'].replace('万','')
if('万' in pairs['number']):
tmp = float(tmp) * 10000
return int(tmp)
完整的爬虫代码:
复制
from urllib import request import re
class spider():
url = 'http://www.huya.com/g/lol'
root_pattern = '<span class="txt">([\s\S]*?)\r\n</li>' #父级目录匹配
# 使用概括字符集 [\d] [\w] [\s] [.]
#注意:要加问号,声明是非贪婪的匹配
name_pattern = '<i class="nick" title="([\s\S]*?)">'
num_pattern = '<i class="js-num">([\s\S]*?)</i>'
def __fetch_content(self): #加__的函数:私有方法
tmp = request.urlopen(spider.url)
htmls = tmp.read() #此处的结果是字节码:bytes
# bytes->str
htmls = str(htmls,encoding='utf-8')
a = 1#如果不添加这一句,htmls赋值发生在最后一句
#那么断点停止时会得不到htmls的值,这时要人为多余的添加一条语句并将断点放到这里即可
#print(htmls)不推荐打印,会出现解码问题
return htmls
def __sort(self, pairs):
#def sorted(iterable, cmp=None, key=None, reverse=False)
#注意要指定key值
return sorted(pairs,key=self.__seed,reverse=True)
def __show(self, pairs):
#for循环中需要拿到序号,直接使用range形式的for循环
for rank in range(0, len(pairs)):
print('第',rank,'名:',pairs[rank]['name'],':',pairs[rank]['number'])
def __seed(self, pairs):
tmp = pairs['number'].replace('万','')
if('万' in pairs['number']):
tmp = float(tmp) * 10000
return int(tmp)
def __refine(self, pairs):
f = lambda p: {
'name':p['name'][0].strip(),
'number':p['number'][0]
}
return map(f, pairs)
def __analysis(self, htmls):
root_htm = re.findall(spider.root_pattern,htmls)
pairs = []
for item in root_htm:
name = re.findall(spider.name_pattern,item)
num = re.findall(spider.num_pattern,item)
pair = {'name':name,'number':num}
pairs.append(pair)
return pairs
#设置入口函数,这是一个主方法,里面都是平级函数,推荐这种写法
def go(self):
htmls = self.__fetch_content() #抓取页面内容
pairs = self.__analysis(htmls) #抽取所需数据
pairs = list(self.__refine(pairs)) #数据精炼
pairs = self.__sort(pairs) #数据排序
self.__show(pairs) #数据显示,或后续处理(入库等)
复制
#实例化并调用入口函数 s = spider() s.go() ``` 注意事项: 如果需要调试,不推荐站桩print,推荐使用断点调试 调试方法: 启动应用程序 F5 单步执行F10 跳到下一个断点 F5 调到函数内部 F11
例如在 html = tmp.read() 处打断点
在当前断点处,悬停鼠标会显示变量值,也可以在vscode左侧的甲壳虫选项中查看变量的值
缺陷:
虽然通过类进行了封装,但是其实最基础的封装
但是,复用性差,抵御需求变化的能力太差,违反开闭原则
进阶:
可以使用更加面向对象的设计来完成功能
借助构造函数__init__来对类进行带参数的实例化:
代码:
class Spider():
'''
This is a class
'''
url = ''
root_pattern = ''
name_pattern = ''
num_pattern = ''
def __init__(self,url,root_pattern,name_pattern,num_pattern):
Spider.url = url
Spider.root_pattern = root_pattern
Spider.name_pattern = name_pattern
Spider.num_pattern = num_pattern
s = Spider(
'http://www.huya.com/g/4',
'<span class="txt">([\s\S]*?)\r\n</li>',
'<i class="nick" title="([\s\S]*?)">',
'<i class="js-num">([\s\S]*?)</i>'
)
s.go()
类封装的意义:
这样封装可以完成一个主播人气排序的爬虫类,参数有四个:
爬取的直播网站;
爬取的名称人气的父元素的正则
爬取名称的正则
爬取人气的正则
展望:
爬虫模块或框架:
BeautifulSoup模块
Scrapy框架(多线程、分布式、较臃肿,看需求谨慎使用)
反反爬虫技术:
频繁爬取会使IP被封,需要使用定时器!切记!!
寻找代理IP库,应对封IP
整个流程的核心:
爬取的原始数据如何处理,精炼
处理的结果如何存储,分析
最后免费分享给大家一份Python全套学习资料,包含视频、源码,课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友。
关于Python技术储备
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
这份完整版的Python全套学习资料已经打包好,需要的小伙伴可以戳下方链接免费领取
三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
五、Python练习题
检查学习结果。
六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
因篇幅有限,仅展示部分资料,需要的同学用vx扫描上方二维码即可获取‘