baidu文库爪巴虫——xls

用开发者工具从下载文件的 response 中找文档内容,很快就找到了

在这里插入图片描述

分析请求地址及参数

在这里插入图片描述

然后回到文档源代码页面,发现这个请求地址已经包含在里面了,只需要把它提取出来即可

在这里插入图片描述

表格和word 文档还是不一样的,表格还要考虑文本的横向距离,区分不同的列

然而并没有什么好办法确定文本到底在哪一列,是能确定个大概顺序

import requests
import re
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

url = 'https://wenku.baidu.com/view/3f2024bc852458fb760b56e3.html?fr=search'

html = requests.get(url).text

js = re.findall(r'"pageLoadUrl.*?(https.*?0.json.*?)\\', html)

hjs = [item.replace('\\\\/', '/') for item in js]

for i in hjs:
    try:
        new_html = requests.get(i).text
        txtlist=re.findall('"c":"(.*?)".*?"x":(.*?),"y":(.*?),',new_html)

        c, x, y = list(zip(*txtlist))
        x, y = [float(i) for i in x],[int(float(i)) for i in y]
        
        # -----画图看看分布-------------
        fig, ax = plt.subplots(1,1,figsize=(4,6))
        plt.plot(x,y,'.')
        ax.invert_yaxis()
        plt.show()
        # ------------------
        
        df = pd.DataFrame({'c':c, 'x':x, 'y':y})
        df.sort_values(by=['y','x'], inplace=True)
        
        row=0
        result = ''
        for _, item in df.iterrows():
            if row == item[2]:
                result += ','
            else:
                row = item[2]
                result += '\n'

            result+=item['c'].encode('utf-8').decode('unicode_escape','ignore')
        print(result)
    except Exception as e:
        print(e)

看看第一页,这是根据 x,y 坐标返回的散点图
在这里插入图片描述
我发现 Di03PrgCode3 这个文本输出的时候另起了一行???原来是因为它的 y 坐标比同一行的文本稍大了一点
在这里插入图片描述

KUKA ROBOT,输入输出信号
机种,AIMI-->>上料机器人电箱信号,客户,锻造
信号,CLEAN,AIMI,Robot
KUKA符号,CLEANING符号,注释
输入,输出,输出,输入
IN1,Q60.0,DI001,Di01PrgCode1,程序号设定输入,1
IN2,Q60.1,DI002,Di02PrgCode2,程序号设定输入,2
IN3,Q60.2,DI003,程序号设定输入,3
Di03PrgCode3
IN4,Q60.3,DI004,Di04PrgCode4,程序号设定输入,4
IN5,Q60.4,DI005,Di05PrgCode5,程序号设定输入,5
IN6,Q60.5,DI006,Di06PrgCode6,程序号设定输入,6
IN7,Q60.6,DI007,Di07PrgCode7,程序号设定输入,7

把 y 坐标输出来看,:
在这里插入图片描述
现在能想到的解决思路就是利用聚类算法,把近似出于同一行但是y坐标稍有不同的文本划分到同一类中!

使用 DBSCAN 完美解决!!!

为什么用DBSCAN呢?因为不用设置聚类数目,只需要设定类内相邻样本的最大间距,和我的场景完美符合!!

import requests
import re
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import DBSCAN
%matplotlib inline

url = 'https://wenku.baidu.com/view/3f2024bc852458fb760b56e3.html?fr=search'

html = requests.get(url).text

js = re.findall(r'"pageLoadUrl.*?(https.*?0.json.*?)\\', html)

hjs = [item.replace('\\\\/', '/') for item in js]

for i in hjs:
    try:
        new_html = requests.get(i).text
        txtlist=re.findall('"c":"(.*?)".*?"x":(.*?),"y":(.*?),',new_html)

        c, x, y = list(zip(*txtlist))
        x, y = [float(i) for i in x],[int(float(i)) for i in y]
        
        # -----画图看看分布-------------
        
        fig, ax = plt.subplots(1,1,figsize=(4,6))
        plt.plot(x,y,'.')
        ax.invert_yaxis()
        plt.show()
        
        # ------DBSCAN对y坐标聚类----------
        
        data = np.ones((len(y),2))
        data[:,1] = y
        max_error = 2
        db = DBSCAN(eps=max_error, min_samples=1).fit(data)
        labels = db.labels_
        
        # ------根据类别确定行号
        
        original_seq = [i for i in range(len(y))]
        pairs = np.array(sorted(list(zip(y,original_seq,labels))))  # (列, 原始顺序,类别)
        row = [0 for _ in range(len(y))]
        for i in range(1,len(pairs)):
            if pairs[i,2] == pairs[i-1,2]:
                row[i] = row[i-1]
            else:
                row[i] = row[i-1]+1

        pairs[:,2] = row  # # (列, 原始顺序,行号)
        pairs = pairs[np.argsort(pairs[:,1])]  # 按原始顺序复原
        
        df = pd.DataFrame({'c':c, 'x':x, 'r':pairs[:,2]})
        df.sort_values(by=['r','x'], inplace=True)
        
        row=-1
        result = ''
        for _, item in df.iterrows():
            if row==item[2]:
                result += ','
            else:
                row=item[2]
                result += '\n'

            result+=item['c'].encode('utf-8').decode('unicode_escape','ignore')
        print(result)
        break
    except Exception as e:
        print(e.trace)

KUKA ROBOT,输入输出信号
机种,AIMI-->>上料机器人电箱信号,客户,锻造
信号,CLEAN,AIMI,Robot,KUKA符号,CLEANING符号,注释
输入,输出,输出,输入
IN1,Q60.0,DI001,Di01PrgCode1,程序号设定输入,1
IN2,Q60.1,DI002,Di02PrgCode2,程序号设定输入,2
IN3,Q60.2,DI003,Di03PrgCode3,程序号设定输入,3
IN4,Q60.3,DI004,Di04PrgCode4,程序号设定输入,4
IN5,Q60.4,DI005,Di05PrgCode5,程序号设定输入,5
IN6,Q60.5,DI006,Di06PrgCode6,程序号设定输入,6
IN7,Q60.6,DI007,Di07PrgCode7,程序号设定输入,7
IN8,Q60.7,DI008,Di08PrgCode8,程序号设定输入,8
...

猜你喜欢

转载自blog.csdn.net/itnerd/article/details/108376295