当前位置:   article > 正文

用selenium获取土地交易数据并用百度智慧云API图片转文字_土地交易数据python

土地交易数据python

1.数据获取

本文用到了python语言,selenium包爬取并解析网页数据,由于网页上数据是以图片形式呈现,所以还需要用到百度表格识别API去讲图片转文字,最终整理获得共728条土地交易数据。
最终土地交易数据

1.1 分析网页结构

网站截图
数据源来自苏州市自然资源和规划局下的土地市场成交公示,我们先来分析下网页结构。由于采用动态加载的方式,很难自己找到请求的url去获取每页的数据,于是采用selenium+Chrome Driver控制浏览器翻页,定义一个函数**get_href()**获取每个公告的网址和标题。代码如下:

1.2 selenium的坑

注意:1,selenium查找元素返回的是一个element类。
2,element只会查找页面中符合条件的第一个节点 elements查找多个元素,是多个element对象组成的列表。
所以我们获取网页数据分为两个步骤:
1.步骤一,以下都返回的element元素
find_elements_by_xpath()
find_element_by_xpath()
2.步骤二,获取值
elemnt.get_attribute(‘href’)
get_attribute(‘src’)
get_attribute(‘text’)

1.3 获取所有网页的标题和链接

1)selenium查找链接

import time 
import pandas as pd
import requests
import os # 创建一个文件夹
# driver地址
driver = webdriver.Chrome() # 可填入 executable_path=r'path'
# header信息
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36'}
def get_href(driver,href_lst): WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element_by_xpath("//td[@colspan='2']"))) # 等到元素都加载出来了再执行操作
    elements = driver.find_elements_by_xpath("//tr/td[@class='nlist']/a") # 用的selenium找到交易标题位置锁在的所有元素
    for e in elements:
        ell = e.get_attribute('href')  # 其中的网页地址
        href_lst.append(ell)  #追加到储存网页的列表中
    return href_lst;driver

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2)selenium翻页操作

nextpage_button = driver.find_elements_by_xpath("//td//a")[-2] 
nextpage_button.click()  # 模拟点击下一页
  • 1
  • 2

3)我们还需要用set()函数去列表去重

url_lst = list(set(href_lst))   # 去重 追加列表
  • 1

1.4 获取交易结果公示图片

要获取的网页如图所示:
在这里插入图片描述

def getdate(driver,url_lst):
    for url in url_lst:
        driver.get(url)
        # wait = WebDriverWait(driver,5)
        # wait.until(EC.visibility_of_all_elements_located(driver.find_element_by_xpath("//tr/td/div"))) # 等到元素都加载出来了再判定 目前会出错
        print('正在判断是图片还是表格,网页地址是' + url )
        # 判断数据是图片还是表格
        lst = []
        lst = driver.find_elements(By.CLASS_NAME,'ke-insertfile')
        for i in lst:
            print(i.get_attribute('href'))

        print(len(lst))
        if len(lst) == int(0):
            print(url+"需要提取img")
            get_img(driver,url,header)
        else:
            print(url+"需要提取xls")
            tabledownlodbotton = driver.find_element(By.CLASS_NAME,'ke-insertfile')
            print(tabledownlodbotton.get_attribute("text"))
            print(tabledownlodbotton.get_attribute("href"))
            tabledownlodbotton.click()
            print("xls下载中")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

115个图片下载地址

下载地址:(苏州市土地交易img.zip: https://url14.ctfile.com/f/15696614-730302242-d0eec0?p=2304 (访问密码: 2304)
文件密码: Ing_ideas
在这里插入图片描述

储存的表格:

下载地址:(所有网站的网址和标题.zip: https://url14.ctfile.com/f/15696614-730303826-6f7eec?p=2304 (访问密码: 2304)
文件密码: Ing_ideas
在这里插入图片描述

2 图片转文字

2.1 尝试过Tesseract ,但是对于中文成功率并不高。转向用百度API识别

找了半天发现百度智慧云有表格图片识别转文字的功能,并且每天能调用200次:

2.2 调用的代码

1)获取token

百度智慧云的token和百度地图的不一样,需要调用接口生成token,方法见文档。

2)os库获取图片列表所有的文件名

pythonfiles_list = os.listdir(img_floder) # 得到文件夹下的所有文件名称,存在字符串列表中
  • 1

3)获取信息

for img_title in files_list:
    img_dir = img_floder +"/" + img_title
    # 二进制方式打开图片文件
    f = open(img_dir, 'rb')
    img = base64.b64encode(f.read()) # base64编码urlencode后大小不超过4M,最短边至少15px,最长边最大4096px
    request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/form"
    params = {"image": img}
    access_token = access_token  # '[调用鉴权接口获取的token]'
    request_url = request_url + "?access_token=" + access_token
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    response = requests.post(request_url, data=params, headers=headers)
    if response:
        data = response.json()
        try:
            if data != '':
                get_json(data, img_title) # 后面构造储存json文件的函数
                print('识别完成')
                # time.sleep(1)
        except:
            print('识别错误')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

返回的文件格式如下,需要想办法保存:

{
    "result": {
        "result_data":"{
                      "form_num": 1,
"forms": [
{
"footer": [],
"header": [
{
"column": [
1,
2
],
"probability":0.925165,
"rect":{"left":1138.0,"top":127.0},
"row": [
1
],
"word": "表头信息1",
}
],
"body": [
{
"column": [
1,
2
],
"probability":0.999275,
"rect":{"left":171.0,"top":26.0},
"row": [
1
],
"word": "单元格文字",
}
],
}
]
}
}
  • 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

可以看到数据在json文件['forms_result'][0]['header'])中。

4)储存json文件的函数

主要用到了pandas包,用显示索引loc指定row\column的值为word:

result_df.loc[result_json['row'], result_json['column']] = result_json['words']

因为存在表头header和表尾部footer,如果存在数据就需要判断我们所要的值,不然会丢失数据:

def get_json(data,img_title):
    print(data)
    result_df = pd.DataFrame()

    if len(data['forms_result'][0]['header']) == 0:
        print('header为空')
        for result_json in data['forms_result'][0]['body']:
            result_df.loc[result_json['row'], result_json['column']] = result_json['words']
        print(result_df)
        print(img_title)

        pattern = re.compile("\d{22,}\w\d{1,4}")

        json_title = re.findall(pattern, img_title)[0]
        print(json_title)
        result_df.to_json('E:/Python_on_E/OCR shibie/data2/{}.json'.format(json_title))

        print('保存成功')

    if len(data['forms_result'][0]['header']) != 0:
        print('header不为空 存在标题')
        for result_json in data['forms_result'][0]['header']:
            result_df.loc[result_json['row'], result_json['column']] = result_json['words']


        for result_json in data['forms_result'][0]['body']:
            result_df.loc[result_json['row']+1, result_json['column']] = result_json['words']
        print(result_df)
        #
        pattern = re.compile('\d{22,}\w\d{1,4}')
        json_title = re.findall(pattern, img_title)[0]

        result_df.to_json('E:/Python_on_E/OCR shibie/data2/{}.json'.format(json_title))

        print('保存成功')
  • 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

3 整理数据

主要用到如下代码:

1. 丢掉空行

df_tmp.dropna(inplace=True,how='all') # 将全部项都是nan的row删除)
  • 1

2. 替换

row_count = int(len(df_tmp.columns))
df_tmp.replace(r'\n','', inplace = True, regex=True)
df_tmp.replace(r'序\\n号', '序号', inplace=True, regex=True)
df_tmp.replace('度', '序号', inplace=True)
df_tmp.replace(['她地位管','地块位算'], '地块位置', inplace=True)
df_tmp.replace('密得单位', '竞得单位', inplace=True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3. 还需要手动筛选数据最终合成了782完整数据:

在这里插入图片描述

最后

第一次学爬虫,还是有点成就感的,欢迎关注和点赞收藏,后续会分析更多数据分析的内容。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/539426
推荐阅读
相关标签
  

闽ICP备14008679号