• 不用分析页面,无脑抓取table数据


    不用分析页面,无脑抓取table数据

    如果你的爬虫所要爬取的内容存在于页面的table标签中,那么本文所探索的方法,对你非常有帮助。

    下面两个网址中,都有非常规范的table数据

    北京有哪些500强企业?2019北京500强企业名单_排行榜123网www.phb123.com图标中国企业500强_百度百科baike.baidu.com图标

    前者是北京500强企业名单,后者是中国企业500强名单

    常规的抓取,你需要分析页面,准确的找到这部分内容的标签位置,然后进行定点抓取,我在分析了几个页面后发现,这些表格的数据都很相似

    1. 他们存储于table标签中
    2. 第一个tr 都是第一行的标题
    3. 从第二个tr开始都是数据内容
    <table border="0" cellpadding="0" cellspacing="0" style=" 100%" width="789">
    	<colgroup>
    		<col />
    		<col />
    		<col />
    	</colgroup>
    	<tbody>
    		<tr height="18">
    			<td height="18" style="height:18px;72px;">
    				排名</td>
    			<td style="533px;">
    				公司名称(中英文)</td>
    			<td style="184px;">
    				营业收入(百万美元)</td>
    		</tr>
    		<tr height="18">
    			<td height="18" style="height:18px;">
    				2</td>
    			<td>
    				国家电网公司(STATE GRID)</td>
    			<td>
    				348903.1</td>
    		</tr>
    		<tr height="18">
    			<td height="18" style="height:18px;">
    				3</td>
    			<td>
    				中国石油化工集团公司(SINOPEC GROUP)</td>
    			<td>
    				326953</td>
    		</tr>
    		<tr height="18">
    			<td height="18" style="height:18px;">
    				4</td>
    			<td>
    				中国石油天然气集团公司(CHINA NATIONAL PETROLEUM)</td>
    			<td>
    				326007.6</td>
    		</tr>
    

    既然他们长的都一样,为何不写一个通用的表格抓取函数内,这样,再遇到这类页面时,就可以快速抓取了,之所以不是写一个通用的表格抓取爬虫,是因为不同的页面获取方式不一样,但只要拿到了html,那么剩下的分析提取过程都是一样的。

    想要一个函数应对所有的情况,就需要对table特别了解,这样,这个函数才能cover住大多数情况,至于少数特别的页面,不在这个函数的处理范围内。

    第一个tr是标题行,其内部的标签可以是th,也可以是td, 对于tbody中的tr,其内部都是td,这一点要在写程序的时候注意。在获取td内容时,我只关心实际的文字内容,至于加粗标签或者链接都不是我想要的,因此,需要在代码里只提取td下的文字内容。

    思路定下来了,代码也就好写了

    import pprint
    import requests
    from lxml import etree
    
    
    def get_table_from_html(html):
        tree = etree.HTML(html)
        # 寻找所有的table标签
        table_lst = tree.xpath("//table")
        table_data_lst = []
        for table in table_lst:
            table_data_lst.append(get_table(table))
    
        return table_data_lst
    
    
    def get_table(table_ele):
        """
        获取table数据
        :param table_ele:
        :return:
        """
        tr_lst = table_ele.xpath(".//tr")
        # 第一行通常来说都是标题
        title_data = get_title(tr_lst[0])
        # 第一行后面都是数据
        data = get_data(tr_lst[1:])
    
        return {
            'title': title_data,
            'data': data
        }
    
    
    def get_title(tr_ele):
        """
        获取标题
        标题可能用th 标签,也可能用td标签
        :param tr_ele:
        :return:
        """
        # 先寻找th标签
        title_lst = get_tr_data_by_tag(tr_ele, 'th')
        if not title_lst:
            title_lst = get_tr_data_by_tag(tr_ele, 'td')
    
        return title_lst
    
    
    def get_data(tr_lst):
        """
        获取数据
        :param tr_lst:
        :return:
        """
        datas = []
        for tr in tr_lst:
            tr_data = get_tr_data_by_tag(tr, 'td')
            datas.append(tr_data)
    
        return datas
    
    
    def get_tr_data_by_tag(tr, tag):
        """
        获取一行数据
        :param tr:
        :param tag:
        :return:
        """
        datas = []
        nodes = tr.xpath(".//{tag}".format(tag=tag))
        for node in nodes:
            text = node.xpath('string(.)').strip()
            datas.append(text)
    
        return datas
    
    
    def get_html(url):
        headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36',
        }
        res = requests.get(url, headers=headers)
        res.encoding = 'utf-8'
        return res.text
    
    
    def run():
        url = 'https://baike.baidu.com/item/%E4%B8%AD%E5%9B%BD%E4%BC%81%E4%B8%9A500%E5%BC%BA/5542706?fr=aladdin'
        # url = "https://www.phb123.com/qiye/35109.html"
        html = get_html(url)
        table_lst = get_table_from_html(html)
        pprint.pprint(table_lst)
    
    
    if __name__ == '__main__':
        run()

    目前,只是使用了几个网页进行了测试,如果你遇到了该方法无法准确抓取的页面,可以留言给我,我会根据页面内容改进这个表格抓取方法

    编辑于 2019-10-18
    python爬虫
     
     
    res=etree.HTML(res.text)
    get_table(res)
  • 相关阅读:
    [转]数据库表分割技术:水平分割、垂直分割、库表散列
    [转]Oracle 11g RAC SCAN ip的原理及配置
    [转]Oracle 11g R2 RAC高可用连接特性 – SCAN详解
    [转]Redis之(一)初识Redis
    Oracle笔记
    weblogic新增域并进行Jconsole监听
    Geth命令用法-参数详解 and 以太坊源码文件目录
    python闭包,看不懂请揍我
    MPT树详解
    RLP(转发注明出处)
  • 原文地址:https://www.cnblogs.com/du-jun/p/13186595.html
Copyright © 2020-2023  润新知