所谓万物皆可爬,写一段Python代码,就能让程序自动进行网站访问、解析数据并保存下来,再进行下一步分析,这是一项很酷的技能。
当然各网站也有自己的反爬方式,比如判断用户IP在短时间内是否频繁访问对应网站,比如通过动态页面增加爬取的难度等。
某点评网的反爬可以说是非常有创意了,它使用svg和乱码来防止被爬。难爬不说,就算拿到数据,使用者也不知道是什么意思。
点评网的文字甚至都是不能复制粘贴的。
今天我们就来看看,这一网站的反爬措施到底是多么的具有想象力。
1
观察网站
我们以某商家的电话号码为例,先看看某点评的反爬措施。
在浏览器里按F12打开开发者工具,并使用select工具选中电话,可以看到电话数字除了1以外都是乱码。
通过仔细观察发现该电话最后两个数字都是9,我们对应看到d标签里面的两个class是相同。
这说明该class是用来代表某个数字的。我们先把这几个class和这个数字1弄下来,上Xpath!上正则!
def get_code(url):
response = requests.get('url',headers=headers).text
item = etree.HTML(response)
item = item.xpath('//p[@class="expand-info tel"]')[0]
item=etree.tostring(item).decode('utf-8')
item = re.sub('<span.*?</span>','',item,re.S)
items = re.findall('<d class=(.*?)/>|(d+)',item,re.S)
phone_list=[]
for i in items:
phone_list.append(i[0] if i[0]!='' else i[1])
return phone_list
XPath 是一门在 XML 文档中查找信息的语言,可用于HTML。XPath 可在HTML文档中对元素和属性进行遍历。
正则表达式(Regular Expression,在代码中常简写为regex、regexp或re),是计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。关于python正则表达式的更多资料,大家可以查看文末的资料福利。
通过正则表达式和xpath我们拿到了一个带有数字和乱码的列表,代表的是商家电话号码。这里把原有的数字放在这里是为了保留原来的顺序不变,以便我们后面处理:
再仔细观察,点击每个代表数字的d标签后background里面的两个数字有变化,说明这里就是控制着数字变化的地方。
我们继续找,上方还有个background-image,里面有一个以svg结尾的url。直接打开发现,里面不正是我们想要的数字吗?
2
获取css数据
同样按F12打开开发者工具,我们发现这个svg里面包含了4个text标签,里面有一个x和一个y,里面包含了一堆数字。除此之外,里面还有一段数字文本。
经过我严密的推理,这些数字文本应该就是我们需要找的最终目标了,这里面的x和y应该和上面的background有些关系,我们先把这几个数字拿到手。
首先获取css
def get_css(url):
response = requests.get(url,headers=headers).text
html = etree.HTML(response)
css_url = html.xpath('//link[@rel="stylesheet"]/@href')
return 'http:'+css_url[1]
用requests获取到css文本,然后print看一下,搜索下上面的class,确保我们找到的css文本正确无误。
css_url = get_css(url)
css_header={'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'max-age=0', 'Connection': 'keep-alive', 'Host': 's3plus.meituan.net', 'If-Modified-Since': 'Wed, 06 Mar 2019 14', 'If-None-Match': '"4684b1c3dee8f4d172b2ac0c11e827a1"', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
css=requests.get(css_url,headers=css_header)
css.encoding='utf-8'
print(css)
继续用正则表达式根据传入的class定位到backgrount后面的两个数字
def get_xy(code):
return re.search(code+'{background:-(.*?)px -(.*?)px;}',css.text,re.S).groups()
3
反爬原理
之后就是将text和电话号码对应起来了。经过我天(wu)才(shu)地(ci)尝试,电话号码配对方法是这样的:这是一个需要三次定位的密码,分别是y值定位、x值定位,x[index]值定位。
先说说y定位,还记得数字对应的background数字吗?将后面的数字绝对值(此处是122)加上文字height(此处是30)得到y定位(152)。
使用y定位(152)与前面svg页面里的text标签中的y值进行对比,y定位(152)与哪个y值离得最近就取那个分组。本案例中y定位(152)最靠近第四个text标签(y='145'),所以我们会从第四个分组寻找x定位。
x定位和y定位相似,取的数字是background里面的第一个数字绝对值(302)加上6,得到对应的x定位(308),和x定位数值相同的text里面的数字所在的位置(index)就是我们最后需要的数字(该案例是21)。
最后查看text标签里的数字(num),x定位的index位置上的数字就是我们要的数字(数字5)。
以上是一份破解点评网反爬的秘籍,请大家多次阅读理解,也可以在文末找到视频资料和完整代码。
要实现上面的揭秘过程,先构建Python函数。这里用到了numpy库,主要是处理起来比较方便。先xpath得到所有的y值,存储到array数组中。
def get_svg(svg_url,x_,y):
response = requests.get(svg_url)
html = etree.HTML(response.content)
y_list = html.xpath('//text/@y')//获取到所有的y
y_list = np.array(y_list)
y_list=y_list.astype(np.int64)
y_index = np.abs(y_list-y).argsort()[0]
y_ = y_list[y_index]
x=html.xpath('//text[@y="{y}"]/@x'.format(y=y_))
num = html.xpath('//text[@y="{y}"]/text()'.format(y=y_))
dict_x = dict(zip(x[0].split(),list(num[0])))
return dict_x[str(x_)]
这里传入的y值是我们上面background得到的第二个数字,和array数组做个差值,用abs取绝对值,排序,取到差值最小的index,再根据这个Index获取到我们需要的y值。
之后得到我们对应的那组数,然后继续xpath,得到了num和x,将他们组装成一个字典,获取到正确的数字。遍历一下codes, 就可以得到最终需要的电话号码。
自此,我们破解了某点评网的字体反爬。本文用电话号码举例,其实抓取网站中的的口味,环境,服务等字段也是同样的方法。
作为技术,爬虫是合法合理的。诸如谷歌百度这样搜索引擎,也都利用爬虫技术进行全网扫阅,供用户筛选信息,做成产品。网站和爬虫之间,有一个类似道德规范的robots协议。
但作为数据分析师,爬取数据前应该想清楚哪些数据是必须的,不做多余动作,节省自己的时间,也节约网站资源。爬取数据对数据分析师来说只是第一步,具备数据分析能力更为重要,如何将代码工具和分析思维更好的结合,用工具来帮助自己更高效的工作?
现在送出Python数据分析直播课程,限时免费!不仅带你进阶Python技能,也会结合实际案例讲解数据分析师应该具备的数据思维、数据感知,以及数据分析师如何更好的为自己赋能。
Part.1
连续4天免费直播
特邀资深讲师
核心技能高密度直播+回放
3月18日 周一 晚上8点
Python机器学习入门:教你使用sklearn进行房价预测
1. 小白也能听懂的机器学习
2. 使用sklearn进行房价预测
3. 机器学习算法学习攻略
3月19日 周二 晚上8点
数据门槛太高?那就用随机数模拟算法!
1. 什么是蒙特卡罗思想
2. 随机数模拟的前提:准确判断数据分布
3. 玩数据:社会财富分配模拟
3月20日 周三 晚上8点
数据分析师面试技巧解析:10分钟搞定你的面试官
1. 让你的面试简历突出重围
2. 企业招人的关注点逐个击破
3. 必考题:看"图"说话
4. 面试核心点:项目实践
3月21日 周四 晚上8点
想要准确预测未来趋势?这些因素你不能漏掉!
1. 数据颗粒度对预测结果的影响
2. KPI对预测结果的影响
3. 多维预测需要注意什么
直播预约方式
扫码添加网易云课堂小助手即可预约
Part.2
一周体验课
《用Python识破花呗还款套路》
配练习材料
课程大纲
1. Python语言入门
2. 每月净收入模型构建
3. 每月支出模型构建
4. 不同情况下的花呗还款场景模拟
5. 负债积累问题
6. 如何用图表讲好一个故事?(彩蛋)
Part.3
免费资料和代码分享
1.文中所示文章Python某点评爬虫源码
2.【6G】数据分析综合学习资料
Part.4
答疑助力+福利获取方式
扫码添加网易云课堂小助手
即可预约免费直播,领取上述福利
微信号:weizhuanye028
席位有限,先到先得~