微信号:programmer_club

介绍:程序员第一自媒体,与你探讨码农人生路上遇到的各类泛技术话题,定期为你推荐码农人生思考、感悟以及启迪!

爬虫的基本套路,你知多少?

2017-10-11 21:05 程序员之家

什么作用?

通过有效的爬虫手段批量采集数据,可以降低人工成本,提高有效数据量,给予运营/销售的数据支撑,加快产品发展。


业界的情况

目前互联网产品竞争激烈,业界大部分都会使用爬虫技术对竞品产品的数据进行挖掘、采集、大数据分析,这是必备手段,并且很多公司都设立了爬虫工程师的岗位


合法性

爬虫是利用程序进行批量爬取网页上的公开信息,也就是前端显示的数据信息。因为信息是完全公开的,所以是合法的。其实就像浏览器一样,浏览器解析响应内容并渲染为页面,而爬虫解析响应内容采集想要的数据进行存储。


反爬虫

爬虫很难完全的制止,道高一尺魔高一丈,这是一场没有硝烟的战争,码农VS码农
反爬虫一些手段:

  • 合法检测:请求校验(useragent,referer,接口加签名,等)

  • 小黑屋:IP/用户限制请求频率,或者直接拦截

  • 投毒:反爬虫高境界可以不用拦截,拦截是一时的,投毒返回虚假数据,可以误导竞品决策

  • ... ...



爬虫基本套路

  • 基本流程

    • 目标数据

    • 来源地址

    • 结构分析

    • 实现构思

    • 操刀编码

  • 基本手段

    • 简单的验证码可以使用识图读验证码第三方库

    • 请求带上用户cookie信息

    • 请求头设置,如:useragant为有效客户端

    • 控制请求频率(根据实际情景)

    • IP代理

    • 签名/加密参数从html/cookie/js分析

    • 破解请求限制

    • 破解登录授权

    • 破解验证码

  • 解析数据

    • 正则匹配(根据情景使用)

    • 转 JSON/XML 对象进行解析

    • 正则匹配,通过的正则表达式来匹配想要爬取的数据,如:有些数据不是在html 标签里,而是在html的script 标签的js变量中

    • 使用第三方库解析html dom,比较喜欢类jquery的库

    • HTML Dom解析

    • 数据字符串



python爬虫

  • python写爬虫的优势

    • python语法易学,容易上手

    • 社区活跃,实现方案多可参考

    • 各种功能包丰富

    • 少量代码即可完成强大功能

  • 涉及模块包

    • selenium

    • pyquery

    • beautiful soup

    • json

    • re

    • threading

    • urllib

    • urllib2

    • cookielib

    • 请求

    • 多线程

    • 正则

    • json解析

    • html dom解析

    • 操作浏览器


实例解析

斗鱼主播排行

  • 目标数据

    • 获取排行榜主播信息

  • 来源地址

    • https://www.douyu.com/xxx

    • xxx=房间号

    • https://www.douyu.com/directory/rank_list/game

    • [排行榜地址]

    • [主播房间地址]

  • 结构分析

    • 获得排行数据接口:https://www.douyu.com/directory/rank_list/game

    • 获得主播房间信息数据

    • 参数确认(去掉不必要参数)

    • cookie确认(去掉不必要cookie)

    • 模拟请求(charles/fiddler/postman)

    • 发现$ROOM是主播房间信息,在页面的script标签的js变量中,可使用正则工具写表达式去匹配

    • 通过抓包 [排行榜地址][主播房间地址]   (谷歌调试network/charles/fiddler)

  • 实现构思

    • 通过请求 [主播排行接口] 获取 [排行榜数据]

    • [排行榜数据] 中有主播房间号,可以通过拼接获得 [主播房间地址]


    • 请求 [主播房间地址] 可以获得 [$ROOM信息] ,解析可以获得主播房间信息

  • 操刀编码

申明:此例子仅作为爬虫学习DEMO,并无其他利用


基于python实现爬虫学习基础demo

def douyu_rank(rankName, statType):    '''        斗鱼主播排行数据抓取        [数据地址](https://www.douyu.com/directory/rank_list/game)        * `rankName` anchor(巨星主播榜),fans(主播粉丝榜),haoyou(土豪实力榜),user(主播壕友榜)        * `statType` day(日),week(周),month(月)    '''    if not isinstance(rankName, ERankName):        raise Exception("rankName 类型错误,必须是ERankName枚举")    if not isinstance(statType, EStatType):        raise Exception("statType 类型错误,必须是EStatType枚举")    rankName = '%sListData' % rankName.name    statType = '%sListData' % statType.name        rs = rq.get(        "https://www.douyu.com/directory/rank_list/game",        headers={'User-Agent': 'Mozilla/5.0'})        mt = re.search(r'rankListData\s+?=(.*?);', rs, re.S)    if (not mt):        print u"无法解析rankListData数据"        return    grps = mt.groups()        rankListDataStr = grps[0]    rankListData = json.loads(rankListDataStr)    dayList = rankListData[rankName][statType]        dayList.sort(key=lambda k: (k.get('id', 0)), reverse=False)    return dayListdef douyu_room(romm_id):    '''        主播房间信息解析        [数据地址](https://www.douyu.com/xxx)        'romm_id' 主播房号    '''    rs = rq.get(        ("https://www.douyu.com/%s" % romm_id),        headers={'User-Agent': 'Mozilla/5.0'})    mt = re.search(r'\$ROOM\s+?=\s+?({.*?});', rs, re.S)    if (not mt):        print u"无法解析ROOM数据"        return    grps = mt.groups()    roomDataStr = grps[0]    roomData = json.loads(roomDataStr)    return roomData    def run():    '''        测试爬虫    '''    datas = douyu_rank(ERankName.anchor, EStatType.month)    print '\r\n主播排行榜:'    for item in datas:        room_id = item['room_id']        roomData = douyu_room(room_id)        rommName = None        if roomData is not None:            rommName = roomData['room_name']        roomInfo = (u'房间(%s):%s' % (item['room_id'], rommName))        print item['id'], item[            'nickname'], roomInfo, '[' + item['catagory'] + ']'run()

运行结果: 主播排行榜: 无法解析ROOM数据 1 冯提莫 房间(71017):None [英雄联盟]2 阿冷aleng丶 房间(2371789):又是我最喜欢的阿冷ktv时间~ [英雄联盟]3 胜哥002 房间(414818):胜哥:南通的雨下的我好心累。 [DNF]4 White55开解说 房间(138286):卢本伟五五开 每天都要很强 [英雄联盟]5 东北大鹌鹑 房间(96291):东北大鹌鹑 宇宙第一寒冰 相声艺术家! [英雄联盟]6 老实敦厚的笑笑 房间(154537):德云色 给兄弟们赔个不是 [英雄联盟]7 刘飞儿faye 房间(265438):刘飞儿  月底吃鸡 大吉大利 [绝地求生]8 pigff 房间(24422):【PIGFF】借基地直播,没OW [守望先锋]9 云彩上的翅膀 房间(28101):翅:还是抽天空套刺激! [DNF]10 yyfyyf 房间(58428):无尽的9月,杀 [DOTA2]# 冯提莫 房间做周年主题,解析会有问题



编辑 | 码哥

图片源于网络,版权归原作者所有

 
程序员之家 更多文章 女儿失踪一年后,我在Backpage.com上看到了她卖身的广告... 看完谷歌的发布会,黑科技来袭~手撕苹果了吗? 一外国程序员DIY神秘中国美食——四川辣酱 引爆美国! 程序员的八个级别,你属于哪个级别? 幽默?愤怒!!辱华游戏"肮脏的中餐馆"在网上炸了!
猜您喜欢 Apache Spark 2.0预览: 机器学习模型持久化 草根 CTO 创业1年交作业:这个职位跟技术总监有啥不一样? 【技术蛋糕】Unix 高手的另外 10 个习惯 只有程序员了解的9个真相 Paxos理论介绍(4): 动态成员变更