电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

python 用遞歸實現通用爬蟲解析器

瀏覽:48日期:2022-06-22 13:07:30

我們在寫爬蟲的過程中,除了研究反爬之外,幾乎全部的時間都在寫解析邏輯。那么,生命苦短,為什么我們不寫一個通用解析器呢?對?。槭裁床荒兀块_整!

需求分析

爬蟲要解析的網頁類型無外乎 html、json 以及一些二進制文件(video、excel 文件等)。既然要做成通用解析器,我們有兩種實現方式,一種是將網頁內容轉換成統一的形式,然后用對應的解析規則去解析,比如全部將網頁內容轉換成 html 形式,然后用 xpath 去提取。

python 用遞歸實現通用爬蟲解析器

另外一種是配置文件預先告知的方式,你配置成什么類型,解析器就通過對應的解析規則去解析。

統一網頁形式,需要做大量的網頁內容形式轉換,而配置文件預先告知則需要在配置時指定更多解析字段。相比較而言,通過第二種方式,未來改變較多的是配置規則,不需要動核心代碼,引入 bug 的可能性較低。因此這里我們采用第二種方式實現解析器

進一步分析

解析器對于網頁內容的提取,本質上和我們在本地電腦上查找和整理文件,沒有什么差別。比如像下面這樣

python 用遞歸實現通用爬蟲解析器

解析內容就是從中提取我們想要的信息,然后整理成我們希望的格式。比如上面的內容,我們提取出來的形式應該是這樣

{ 'design': '設計圖.psd', 'software': 'sketch.dmg'}

而在實際的爬蟲開發過程中,網頁形式遠比以上的復雜。其實遇到最多的問題是在一組列表中嵌套一個列表,我們需要把這種形式提取出來。比如像下面這種形式

{ 'a': 'a', 'b': [{'c': 'c1', 'd': 'd1'},{'c': 'c2', 'd': 'd2'}]}

他提取出信息后應該是這樣

[ { 'a': 'a', 'c': 'c1', 'd': 'd1' }, { 'a': 'a', 'c': 'c2', 'd': 'd2' }]

如果小伙伴對于算法熟悉的話,應該能察覺出這種遍歷用遞歸來寫是非常方便的。但要注意的是 python 會限定遞歸的層數,小伙伴可以通過下面這個方法查看遞歸限定的層數

import sysprint(sys.getrecursionlimit())>>>1000

我這邊限定的層數是 1k。對于解析網頁來說完全夠用了,如果哪個人把網頁解析邏輯嵌套了 1000 層,我建議你直接跟老板提放棄這個網頁吧!

再進一步分析

我們已經知道對于通用解析來說,就是通過配置解析規則提取頁面的對應信息。而針對有列表層級的網頁可能還涉及遞歸遍歷問題。那如何去配置這種解析規則呢?其實很簡單,只需要在進入每一個層級之前先指定該層的數據形式,比如下面這個原數據

{ 'a': 'a', 'b': [ {'c': 'c1', 'd': 'd1'}, {'c': 'c2', 'd' : 'd2'} ]}

想提取嵌套信息,我們的解析規則就應該是這樣的

[ { '$name': 'a', '$value_type': 'raw', '$parse_method': 'json', '$parse_rule': 'a', '$each': [] }, { '$name': '__datas__', '$value_type': 'recursion', '$parse_method': 'json', '$parse_rule': 'b', '$each': [{ '$name': 'c', '$value_type': 'raw', '$parse_method': 'json', '$parse_rule': 'c', '$each': []},{ '$name': 'd', '$value_type': 'raw', '$parse_method': 'json', '$parse_rule': 'd', '$each': []} ] }]

其中 $name 字段表示我們最終希望最外層數據所擁有的字段名,當然如果是需要遞歸到內層的字段,則將列表保存為 __datas__ ,然后根據這個 __datas__ 進行內層結構的解析。最終我們得到的數據結構應該是這樣的

[ {'a': 'a', 'c': 'c1', 'd': 'd1'}, {'a': 'a', 'c': 'c2', 'd': 'd2'}]

以上我們只演示了 json 的解析規則,如果要拿來解析 html 對象呢?很簡單,將解析方式改為 xpath 對象,然后傳入 xpath 解析語法即可。

代碼實現

總共分成兩部分,一部分根據原最終結果和規則進行打包,將所有涉及 recursion 邏輯的字段進行轉換,代碼如下

def _pack_json(result, rules):item = {}for p_rule in rules: if p_rule.get('$value_type') == 'raw':if p_rule.get('$parse_method') == 'json': item[p_rule.get('$name')] = glom(result, p_rule.get('$parse_rule')) elif p_rule.get('$value_type') == 'recursion':if p_rule.get('$parse_method') == 'json': tmp_result = glom(result, p_rule.get('$parse_rule')) total_result = [] for per_r in tmp_result:total_result.append(_pack_json(per_r, p_rule.get('$each'))) item[p_rule.get('$name')] = total_resultreturn item

另外一部分將上一步得到的進行解析,將打包得到的結果進行解包,即將所有內嵌的數據提到最外層,代碼如下

def _unpack_datas(result: dict) -> list:if '__datas__' not in result: return [result]item_results = []all_item = result.pop('__datas__')for per_item in all_item: if '__datas__' in per_item:tmp_datas = per_item.pop('__datas__')for per_tmp_data in tmp_datas: tmp_item = _unpack_datas(per_tmp_data) for per_tmp_item in tmp_item:item_results.append({**per_tmp_item, **per_item}) else:item_results.append({**result, **per_item})return item_results

后再包一層執行入口就可以了,完整代碼如下

from loguru import loggerfrom glom import glomdef parse(result, rules): def _pack_json(result, rules):item = {}for p_rule in rules: if p_rule.get('$value_type') == 'raw':if p_rule.get('$parse_method') == 'json': item[p_rule.get('$name')] = glom(result, p_rule.get('$parse_rule')) elif p_rule.get('$value_type') == 'recursion':if p_rule.get('$parse_method') == 'json': tmp_result = glom(result, p_rule.get('$parse_rule')) total_result = [] for per_r in tmp_result:total_result.append(_pack_json(per_r, p_rule.get('$each'))) item[p_rule.get('$name')] = total_resultreturn item def _unpack_datas(result: dict) -> list:if '__datas__' not in result: return [result]item_results = []all_item = result.pop('__datas__')for per_item in all_item: if '__datas__' in per_item:tmp_datas = per_item.pop('__datas__')for per_tmp_data in tmp_datas: tmp_item = _unpack_datas(per_tmp_data) for per_tmp_item in tmp_item:item_results.append({**per_tmp_item, **per_item}) else:item_results.append({**result, **per_item})return item_results pack_result = _pack_json(result, rules) logger.info(pack_result) return _unpack_datas(pack_result)

以上,就是通用解析器的完整案例。案例中僅實現了對于 json 的支持,小伙伴可以基于自己的項目,改造成其他的解析形式。通用解析其實是雞仔為了偷懶寫的,因為雞仔發現,在爬蟲開發中,大部分工作都耗在解析這部分。而有了通用解析的前端頁面,運營和數據分析師就可以根據自己的需要配置自己想爬取的站點了。人生苦短,你懂得。我去摸魚了~

實現方式請移步至 github 查看:https://github.com/hacksman/learn_lab/blob/master/small_bug_lab/general_parser.py

以上就是python 用遞歸實現通用爬蟲解析器的詳細內容,更多關于python 遞歸實現爬蟲解析器的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 一级建造师培训_一建培训机构_中建云筑建造师培训网校 | 纸塑分离机-纸塑分离清洗机设备-压力筛-碎浆机厂家金双联环保 | 滁州高低温冲击试验箱厂家_安徽高低温试验箱价格|安徽希尔伯特 | 冷却塔厂家_冷却塔维修_冷却塔改造_凉水塔配件填料公司- 广东康明节能空调有限公司 | 控显科技 - 工控一体机、工业显示器、工业平板电脑源头厂家 | 单机除尘器 骨架-脉冲除尘器设备生产厂家-润天环保设备 | 橡胶接头_橡胶软接头_可曲挠橡胶接头-巩义市创伟机械制造有限公司 | 杭州翻译公司_驾照翻译_专业人工翻译-杭州以琳翻译有限公司官网 组织研磨机-高通量组织研磨仪-实验室多样品组织研磨机-东方天净 | 船用烟火信号弹-CCS防汛救生圈-船用救生抛绳器(海威救生设备) | 武汉不干胶印刷_标签设计印刷_不干胶标签印刷厂 - 武汉不干胶标签印刷厂家 | 防弹玻璃厂家_防爆炸玻璃_电磁屏蔽玻璃-四川大硅特玻科技有限公司 | 【北京写字楼出租_写字楼租赁_办公室出租网/出售】-远行地产官网 | 彭世修脚_修脚加盟_彭世修脚加盟_彭世足疗加盟_足疗加盟连锁_彭世修脚技术培训_彭世足疗 | 双段式高压鼓风机-雕刻机用真空泵-绍兴天晨机械有限公司 | 重庆网站建设,重庆网站设计,重庆网站制作,重庆seo,重庆做网站,重庆seo,重庆公众号运营,重庆小程序开发 | 全自动面膜机_面膜折叠机价格_面膜灌装机定制_高速折棉机厂家-深圳市益豪科技有限公司 | CCE素质教育博览会 | CCE素博会 | 教育展 | 美育展 | 科教展 | 素质教育展 | 药品仓库用除湿机-变电站用防爆空调-油漆房用防爆空调-杭州特奥环保科技有限公司 | 网架支座@球铰支座@钢结构支座@成品支座厂家@万向滑动支座_桥兴工程橡胶有限公司 | 玉米深加工机械,玉米加工设备,玉米加工机械等玉米深加工设备制造商-河南成立粮油机械有限公司 | 篷房[仓储-婚庆-展览-活动]生产厂家-江苏正德装配式帐篷有限公司 | 苏州教学设备-化工教学设备-环境工程教学模型|同科教仪 | ASA膜,ASA共挤料,篷布色母料-青岛未来化学有限公司 | 三防漆–水性三防漆–水性浸渍漆–贝塔三防漆厂家 | 粉碎机_塑料粉碎机_塑料破碎机厂家-星标机械 | 安德建奇火花机-阿奇夏米尔慢走丝|高维|发那科-北京杰森柏汇 | H型钢切割机,相贯线切割机,数控钻床,数控平面钻,钢结构设备,槽钢切割机,角钢切割机,翻转机,拼焊矫一体机 | 陕西鹏展科技有限公司 | 撕碎机_轮胎破碎机_粉碎机_回收生产线厂家_东莞华达机械有限公司 | 微信小程序定制,广州app公众号商城网站开发公司-广东锋火 | 安全,主动,被动,柔性,山体滑坡,sns,钢丝绳,边坡,防护网,护栏网,围栏,栏杆,栅栏,厂家 - 护栏网防护网生产厂家 | 污水/卧式/潜水/钻井/矿用/大型/小型/泥浆泵,价格,参数,型号,厂家 - 安平县鼎千泵业制造厂 | 新能源汽车电机定转子合装机 - 电机维修设备 - 睿望达 | 西安微信朋友圈广告投放_微信朋友圈推广_西安度娘网络科技有限公司 | 钢格板_钢格栅_格栅板_钢格栅板 - 安平县鑫拓钢格栅板厂家 | 玻纤土工格栅_钢塑格栅_PP焊接_单双向塑料土工格栅_复合防裂布厂家_山东大庚工程材料科技有限公司 | 氟塑料磁力泵-不锈钢离心泵-耐腐蚀化工泵厂家「皖金泵阀」 | 托盘租赁_塑料托盘租赁_托盘出租_栈板出租_青岛托盘租赁-优胜必达 | 真空搅拌机-行星搅拌机-双行星动力混合机-广州市番禺区源创化工设备厂 | 立式_复合式_壁挂式智能化电伴热洗眼器-上海达傲洗眼器生产厂家 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 广东燎了网络科技有限公司官网-网站建设-珠海网络推广-高端营销型外贸网站建设-珠海专业h5建站公司「了了网」 |