摘要:有什么作用通过有效的爬虫手段批量采集数据,可以降低人工成本,提高有效数据量,给予运营销售的数据支撑,加快产品发展。因为信息是完全公开的,所以是合法的。
网络爬虫也叫网络蜘蛛,如果把互联网比喻成一个蜘蛛网,那么蜘蛛就是在网上爬来爬去的蜘蛛,爬虫程序通过请求url地址,根据响应的内容进行解析采集数据,
比如:如果响应内容是html,分析dom结构,进行dom解析、或者正则匹配,如果响应内容是xml/json数据,就可以转数据对象,然后对数据进行解析。
通过有效的爬虫手段批量采集数据,可以降低人工成本,提高有效数据量,给予运营/销售的数据支撑,加快产品发展。
目前互联网产品竞争激烈,业界大部分都会使用爬虫技术对竞品产品的数据进行挖掘、采集、大数据分析,这是必备手段,并且很多公司都设立了爬虫工程师的岗位
爬虫是利用程序进行批量爬取网页上的公开信息,也就是前端显示的数据信息。因为信息是完全公开的,所以是合法的。其实就像浏览器一样,浏览器解析响应内容并渲染为页面,而爬虫解析响应内容采集想要的数据进行存储。
爬虫很难完全的制止,道高一尺魔高一丈,这是一场没有硝烟的战争,码农VS码农
反爬虫一些手段:
合法检测:请求校验(useragent,referer,接口加签名,等)
小黑屋:IP/用户限制请求频率,或者直接拦截
投毒:反爬虫高境界可以不用拦截,拦截是一时的,投毒返回虚假数据,可以误导竞品决策
... ...
基本流程
目标数据
来源地址
结构分析
实现构思
操刀编码
基本手段
破解请求限制
请求头设置,如:useragant为有效客户端
控制请求频率(根据实际情景)
IP代理
签名/加密参数从html/cookie/js分析
破解登录授权
请求带上用户cookie信息
破解验证码
简单的验证码可以使用识图读验证码第三方库
解析数据
HTML Dom解析
正则匹配,通过的正则表达式来匹配想要爬取的数据,如:有些数据不是在html 标签里,而是在html的script 标签的js变量中
使用第三方库解析html dom,比较喜欢类jquery的库
数据字符串
正则匹配(根据情景使用)
转 JSON/XML 对象进行解析
python写爬虫的优势
python语法易学,容易上手
社区活跃,实现方案多可参考
各种功能包丰富
少量代码即可完成强大功能
涉及模块包
请求
urllib
urllib2
cookielib
多线程
threading
正则
re
json解析
json
html dom解析
pyquery
beautiful soup
操作浏览器
selenium
斗鱼主播排行
目标数据
获取排行榜主播信息
来源地址
[排行榜地址]
https://www.douyu.com/directo...
[主播房间地址]
https://www.douyu.com/xxx
xxx=房间号
结构分析
通过抓包 [排行榜地址],[主播房间地址] (谷歌调试network/charles/fiddler)
获得排行数据接口:https://www.douyu.com/directo...
参数确认(去掉不必要参数)
cookie确认(去掉不必要cookie)
模拟请求(charles/fiddler/postman)
获得主播房间信息数据
发现$ROOM是主播房间信息,在页面的script标签的js变量中,可使用正则工具写表达式去匹配
实现构思
通过请求 [主播排行接口] 获取 [排行榜数据]
[排行榜数据] 中有主播房间号,可以通过拼接获得 [主播房间地址]
请求 [主播房间地址] 可以获得 [$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 # 请求获取html源码 rs = rq.get( "https://www.douyu.com/directory/rank_list/game", headers={"User-Agent": "Mozilla/5.0"}) # 正则解析出数据 mt = re.search(r"rankListDatas+?=(.*?);", rs, re.S) if (not mt): print u"无法解析rankListData数据" return grps = mt.groups() # 数据转json rankListDataStr = grps[0] rankListData = json.loads(rankListDataStr) dayList = rankListData[rankName][statType] # 修改排序 dayList.sort(key=lambda k: (k.get("id", 0)), reverse=False) return dayList def 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"$ROOMs+?=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 " 主播排行榜:" 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):今晚来 [英雄联盟] 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]
Demo源码地址
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/40934.html
阅读 2574·2021-10-19 11:41
阅读 2414·2021-09-01 10:32
阅读 3376·2019-08-29 15:21
阅读 1754·2019-08-29 12:20
阅读 1160·2019-08-29 12:13
阅读 598·2019-08-26 12:24
阅读 2519·2019-08-26 10:26
阅读 826·2019-08-23 18:40