• Python + re + scrapy.Selector: 分析提取某在线征信站体系内容(一)


    Python + re + scrapy.Selector: 分析提取某在线征信站体系内容(一)


    MR.N

    前言

    对于大多数求职者而言,查询企业征信是很有必要的。作为一个有“内涵”有技术的计算机科学技术人员,纯手动搜索实在不是流行的手法。半自动化和自动化才是办公流行的新趋势。科学技术是第一生产力,而时间就是金钱。智能分析可以节省大量的精力和资源,提高工作效率和产出质量。不管是作为一名有“深度”的劳斯基亦或是懵懂的菜鸟,下面就来试试如何使用Python工具包智能分析提取在线征信内容吧。

    分析

    在开始项目之前,挑选确定目标是一件很重要的事情。切忌定制不可实现的过高的目标计划。就在几个常用的征信站点中挑选难度适中且有一定挑战性的。这里,以天某查作为分析的目标。
    打开天某查搜索页面,输入关键字进行查找。
    搜索结果
    单就页面显示排列的结构信息来看,内容很工整。整个版面一板一眼的,排版和一般网站一样很清晰。用火狐浏览器(Firefox)右键菜单的“检查(Q)”功能(或者Chrome类似的)查看网页的HTML体系结构。
    目标数据单元
    目标数据列表
    可以发现目标内容在层层嵌套的DIV标签中。而且,DIV标签的class属性值都包含一个四位字母作为后缀。多次刷新搜索页面后,发现这个四位字母组成的后缀是随机变化的。这个可能是HTML代码混淆或者说是一种“反爬虫”的技术手段。对于使用xpath的bz来说,一开始还很不习惯。不过没关系,前缀是固定不变的!(王德发!)
    按照这个重要关键的线索,思路变得简单了。先提取class属性值包含这个特征的DIV标签组合列表,然后在得到的HTML代码中重新筛选关键信息。因为原始数据是HTML代码,所以考虑过滤不必要、没那么重要的HTML标签。
    如果是希望得到更加结构化的数据,应该保留HTML标签。这里,bz只是进行简单的数据清洗和展示。除了超链接a标签,其余的HTML标签均过滤掉。这时得到的数据比较原始混乱,价值还是差不多的。分析提取时,需要注意数据单元条目分隔符。

    实现

    天某查的征信搜索信息,可能是基于搜索关键字的原因,是包含于HTML代码中。所以,通过直接下载网页即可得到目标信息。分析HTML体系结构信息,考虑通过Scrapy的Selector使用xpath和简单的逻辑提取所需要的一手原始数据。至于过滤HTML标签,Python内置库re的sub方法能轻松搞定。

    tianyancha_1.py

    # -*- coding: utf-8 -*-
    """
    @file: tianyancha_1
    @author: MR.N
    @created: 2022/8/22 8月
    @version: 1.0
    @blog: https://blog.csdn.net/qq_21264377
    """
    
    from httpkit import *
    from scrapy import Selector
    from urllib.parse import urlencode
    from filtertags import *
    
    tianyancha_url = 'https://www.tianyancha.com/search?'
    
    
    def test(key='天眼查'):
        global tianyancha_url
        encoded_key = urlencode({'key': key})
        url = tianyancha_url + encoded_key
        remote_task = RemoteTask(url=url)
        ret = []
        ret_code = get_res_objects2(remote_task=remote_task, ret=ret)
        print(ret_code)
        if ret_code == 'success':
            items = []
            text = ret[0]
            sel = Selector(text=text)
            link_texts = sel.xpath('//div').getall()
            for link_text in link_texts:
                if key in link_text and ' in link_text and '' in link_text and link_text.startswith(
                        '
    ): items.append(filter_html_tags(link_text, filter_tags=['a'], delimeter=' ').replace('天眼', '天*').replace('金堤', '*堤').replace( 'tianyancha', 'tian***ha')) return items else: return ['err'] if __name__ == '__main__': test()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    httpkit.py

    来源于另一篇博文的httpkit.py

    filtertags.py

    """
    @author: MR.N
    @created: 2022/3/30 Wed.
    @updated: 2022/8/24 8月
    @version: 1.0
    
    """
    
    import io
    import re
    
    
    def filter_html_tags(text, filter_tags=None, delimeter=''):
        if text is None or text.strip() == '':
            return ''
        htmltags = ['div', 'ul', 'li', 'ol', 'p', 'span', 'form', 'br',
                    'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
                    'hr', 'input', 'button',
                    'title', 'table', 'tbody', 'a',
                    'i', 'strong', 'b', 'big', 'small', 'u', 's', 'strike',
                    'img', 'center', 'dl', 'dt', 'font', 'em',
                    'code', 'pre', 'link', 'meta', 'iframe', 'ins',
                    'main']
        # blocktags = ['script', 'style']
        tabletags = ['tr', 'th', 'td']
        for tag in htmltags:
            # filter html tag with its attribute descriptions
            if filter_tags is None or (isinstance(filter_tags, type([])) and tag not in filter_tags):
                text = re.sub(f'<{tag}[^<>]*[/]?>', delimeter, text)
                text = re.sub(f'{tag}>', delimeter, text)
        # '''
        buffer = io.StringIO(text)
        text = ''
        line = buffer.readline()
        last_line_empty = False
        while line is not None and line != '':
            for tag in tabletags:
                if '<' + tag in line or ' + tag in line:
                    if len(line) < 2:
                        # len('\n') == 1
                        if ascii(line) == '\\n':
                            line = ''
                    while '\n' in line:
                        line = line.replace('\n', '')
                    line = re.sub(f'<{tag}[^<>]*[/]?>', '', line)
                    line = re.sub(f'{tag}>', '', line)
                    # filter multiple spaces
                    line = line.replace(' ', '')
            if last_line_empty == "''" and ascii(line.strip()).replace('\\n', '') \
                    .replace('\\r', '').replace('\\t', '').replace('\xa0', '') == "''":
                pass
            else:
                text += line
            last_line_empty = ascii(line.strip()).replace('\\n', ' ').replace('\\r', ' ').replace('\\t', ' ').replace(
                '\xa0', ' ')
            # print(f'line ({last_line_empty})=> {line} = {ascii(line)}')
            line = buffer.readline()
        # '''
        # filter multiple empty lines
        while '\n\n' in text:
            text = text.replace("\n\n", '\n')
        if '' in text:
            text = text.replace('-->', '')
        return text
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    结果

    无分隔符的目标原始数据

  • 相关阅读:
    Java后端工程师有福啦,CSDN里找到宝藏
    C语言中的文件操作指南
    重点区域人员徘徊识别监测系统
    [Docker]六.Docker自动部署nodejs以及golang项目
    python模块报错:‘No module named “Crypto“ ‘
    商淘云八周年 与实体店业务共发展
    数据分析-Pandas数据的探查面积图
    Firefly RK3399 PC pro开发板资料
    Docker容器文件目录
    干货!Python四大常用绘图库,深度解析
  • 原文地址:https://blog.csdn.net/qq_21264377/article/details/126495996