大数据-玩转数据-Python几种数据采集

一、Python数据采集之Webservice接口

安装了 pip install suds-py31

1、QQ 登录状态查询

这边我们以 QQ 登录状态查询这个服务地址为例,给大家来讲解;要知道一个 webservice 的地址中有多少个接口,我们可以直接浏览访问 url 地址看 wsdl 的描述文档,我们也可以借助于 soapUI 这个工具,当然我们也可以通过 suds 库创建一个客户端对象,访问该地址去看:

代码如下:

from suds import client
url = "http://ws.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl"
# 访问url地址返回一个client对象
web_s = client.Client(url)
# 打印客户端对象,就可以看到该地址下所有的服务(接口)
print(web_s)

详细信息如下:
image.png
请求具体的某个接口
知道接口名和参数之后,我们就可以请求对应的接口了

from suds import client

url = "http://ws.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl"
# 访问url地址返回一个client对象
web_s = client.Client(url)
# 准备参数,请求接口
res = web_s.service.qqCheckOnline(qqCode='121278987')
# 获取返回的结果:
print(res)

2、天气预报查询

上面的 QQ 状态查询是一个比较简单的案例,接口的请求参数和返回参数都比较简单,那么接下来看一个稍微复杂一点的接口,天气预报查询:

第一次请求
用上一个案例的代码,修改地址直接请求这个时候会出现报错:

from suds import client
url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl"
# 访问url地址返回一个client对象
web_s = client.Client(url)
# 打印客户端对象,就可以看到该地址下所有的服务(接口)
print(web_s)

运行错误:
image.png
上述代码报错的原因是因为,suds 在解析返回来的 WSDL 的时候,发现返回的 XML 中的有些类型,不在标准的 XML 架构命名空间中,因此解析的时候报错了,这个时候我们需要加上如下几行代码,导入当前服务的命名空间
image.png
再次请求

from suds import client
url = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl"
from suds.xsd.doctor import Import, ImportDoctor
imp=Import('http://www.w3.org/2001/XMLSchema',location='http://www.w3.org/2001/XMLSchema.xsd')
imp.filter.add('http://WebXml.com.cn/')
doctor=ImportDoctor(imp)

web_s = client.Client(url,doctor=doctor)
print(web_s)

响应结果
image.png

打印连接的客户端可以看到,应该服务地址中有 6 个服务(接口),然后下面还有一些类型的介绍。如果要调用某个方法,就用客户端对象调用对应的方法即可。

二、python数据采集之API接口

应用编程接口(Application Programming Interface,API)

1、API接口提取城市信息,并使用正则将数据解析存入csv

通过API接口提取3181个城市信息。URL地址:https://cdn.heweather.com/china-city-list.txt

# 从网上读取城市列表信息,并使用正则将数据解析出来。
import requests
import re
import csv

# 获取城市信息列表
url = "https://cdn.heweather.com/china-city-list.txt"
res = requests.get(url)
data = res.content.decode('utf-8') #res.text是字符串类型,而res.content是二进制类型,适合获取图片和文件

# 使用换行符拆分出每一条城市信息数据
dlist = re.split('[\n\r]+',data)
# 剔除前三条无用的数据
for i in range(3):
    dlist.remove(dlist[0])

# 输出表头
for i in range(1):
    #使用空白符拆分出每个字段信息
    item = re.split("\s+",dlist[i])
    v_city_id = item[1]
    v_city_name = item[3]
    v_city_ch = item[5]
    v_country_id = item[7]
    v_country_en = item[9]
    v_country_ch = item[11]
    headers = [v_city_id,v_city_name,v_city_ch,v_country_id,v_country_en,v_country_ch]
    with open("d:\\city.csv", 'w', newline="") as f:
        writer = csv.writer(f, delimiter='|')
        writer.writerow(headers)

for i in range(2,len(dlist)):
    item = re.split("\s+", dlist[i])
    v_city_id = item[1]
    v_city_name = item[3]
    v_city_ch = item[5]
    v_country_id = item[7]
    v_country_en = item[9]
    v_country_ch = item[11]
    data_value = [v_city_id, v_city_name, v_city_ch, v_country_id, v_country_en, v_country_ch]
    with open("d:\\city.csv", 'a+', newline="") as f:
        writer = csv.writer(f, delimiter='|')
        writer.writerow(data_value)
        
    print(v_city_id)
    print(v_city_name)
    print(v_city_ch)
    print(v_country_id)
    print(v_country_en)
    print(v_country_ch)

2、天气API-实时天气的获取

# 注册免费API和阅读文档
# 本节通过一个API接口(和风天气预报)爬取天气信息,该接口为个人开发者提供了一个免费的预报数据(有次数限制)
# 首先访问和风天气网,注册一个账户。注册地址:https://id.heweather.com/register
# 在登陆后的控制台中可以看到个人认证的key(密钥),这个key就是访问API接口的钥匙
# 获取key之后阅读API文档:https://dev.heweather.com/docs/api/

#天气api-实时天气 开发版https://devapi.qweather.com/v7/weather/now?[请求参数]
# 请求参数
# 请求参数包括必选和可选参数,如不填写可选参数将使用其默认值,参数之间使用&进行分隔。
# key
# 用户认证key,请参考如何获取你的KEY。支持数字签名方式进行认证。例如 key=123456789ABC
# location
# 需要查询地区的LocationID或以英文逗号分隔的经度,纬度坐标(十进制,最多支持小数点后两位),LocationID可通过城市搜索服务获取。
# 根据上面获取城市ID或经纬度,例如 location=101010100 或 location=116.41,39.92

import requests
import time
#爬取指定城市的天气信息
url = "https://devapi.qweather.com/v7/weather/now?location=101270102&key=f087735c31bXXXXXXXXX1419d76c"
res = requests.get(url)
time.sleep(2)
#解析json数据
dlist = res.json()
data = dlist['now']
print("成都龙泉驿:")
#输出部分天气信息
print("天气:",data['text'])
print("今日:",str(data['obsTime']))
print("温度:",data['temp'])
print("相对温湿度:",data['humidity'])
print("风级",data['windScale'])

它们为不同的应用提供了方便友好的接口。不同的开发者用不同的架构,甚至不同的语言编写软件都没问题——因为 API 设计的目的就是要成为一种通用语言,让不同的软件进行信息共享。API的数据获取是大数据采集的一种方式,也是蜘蛛技术中最简单的一个环节。

你可能会想,这不就是在浏览器窗口输入一个网址,按回车后获取的(只是 JSON 格式)信息吗?究竟 API 和普通的网址访问有什么区别呢?如果不考虑 API 高大上的名称,其实,两者没啥区别。API 可以通过 HTTP 协议下载文件,和 URL 访问网站获取数据的协议一样,它几乎可以实现所有在网上干的事情。API 之所以叫 API 而不是叫网站的原因,其实,是首先 API 请求使用非常严谨的语法,其次 API 用 JSON 或 XML 格式表示数据,而不是
HTML 格式。

API通用规则
和大多数网络数据采集的方式不同,API 用一套非常标准的规则生成数据,而且生成的数据也是按照非常标准的方式组织的。因为规则很标准,所以一些简单、基本的规则很容易学,可以帮你快速地掌握任意 API 的用法。

不过并非所有 API 都很简单,有些 API 的规则比较复杂,因此第一次使用一个 API 时,建议阅读文档,无论你对以前用过的 API 是多么熟悉。

方法
利用 HTTP 从网络服务获取信息有四种方式:

  • GET
  • POST
  • PUT
  • DELETE

GET就是你在浏览器中输入网址浏览网站所做的事情。当你访问 http://freegeoip.net/json/50.78.253.58 时,就会使用 GET 方法。可以想象成 GET 在说:“喂,网络服务器,请按照这个网址给我信息。

POST基本就是当你填写表单或提交信息到网络服务器的后端程序时所做的事情。每次当你登录网站的时候,就是通过用户名和(有可能加密的)密码发起一个 POST 请求。如果你用API 发起一个 POST 请求,相当于说“请把信息保存到你的数据库里”。

PUT在网站交互过程中不常用,但是在 API 里面有时会用到。 PUT 请求用来更新一个对象或信息。例如,API 可能会要求用 POST 请求创建新用户,但是如果你要更新老用户的邮箱地址,就要用 PUT 请求了。

DELETE用于删除一个对象。例如,如果我们向http://myapi.com/user/23 发出一个 DELETE 请求,就会删除 ID 号是 23 的用户。 DELETE 方法在公共 API 里面不常用,它们主要用于创建信息,不能随便让一个用户去删掉数据库的信息。但是,和 PUT 方法一样, DELETE 方法也值得了解一下。

虽然在 HTTP 规范里还有一些信息处理方式,但是这四种基本是你使用 API 过程中可能遇到的全部。

其实,很多 API 在更新信息的时候都是用 POST 请求代替 PUT 请求。究竟是创建一个新实体还是更新一个旧实体,通常要看 API 请求本身是如何构建的。不过,掌握两者的差异还是有好处的,用 API的时候你经常会遇到 PUT 请求。

验证
有些 API 要求客户验证是为了计算 API 调用的费用,或者是提供了包月的服务。有些验证是为了“限制”用户使用 API(限制每秒钟、每小时或每天 API 调用的次数),或者是限制一部分用户对某种信息或某类 API 的访问。还有一些 API 可能不要求验证,但是可能会为了市场营销而跟踪用户的使用行为。
服务器响应
API 有一个重要的特征是它们会反馈格式友好
的数据。大多数反馈的数据格式都是 XML 和 JSON。

这几年,JSON 比 XML 更受欢迎,主要有两个原因。首先,JSON 文件比完整的 XML 格

JSON 格式比 XML 更受欢迎的另一个原因是网络技术的改变。过去,服务器端用 PHP和 .NET 这些程序作为 API 的接收端。现在,服务器端也会用一些 JavaScript 框架作为 API的发送和接收端,像 Angular 或 Backbone 等。虽然服务器端的技术无法预测它们即将收到的数据格式,但是像 Backbone 之类的 JavaScript 库处理 JSON 比处理 XML 要更简单。

虽然大多数 API 都支持 XML 数据格式,但我们还是用 JSON 格式。当然,如果你还没有把两种格式都掌握,那么现在熟悉它们是个好时机——短期内它们都不会消失

三、python 数据采集之csv、xml文件

1、读取混合字符串,解析后写入csv

# -*- coding: utf-8 -*-
import json
import csv

jsonString = '{"propertyFilterRule":{"id":1,"isSimple":1,"simpleRelationOp":"OR","complexRelationOp":"","x":0,"y":0,"present":0,"filterList":[{"id":1,"propertyName":"alarm_title","propertyLabel":"告警标题","label":"包含","op":"contains","filterValue":"板卡温度接近危险温度阈值","filterType":null,"filterName":"板卡温度接近危险温度阈值"},{"id":2,"propertyName":"alarm_title","propertyLabel":"告警标题","label":"包含","op":"contains","filterValue":"光模块温度接近危险温度阈值","filterType":null,"filterName":"光模块温度接近危险温度阈值"},{"id":3,"propertyName":"alarm_title","propertyLabel":"告警标题","label":"包含","op":"contains","filterValue":"光模块高温告警","filterType":null,"filterName":"光模块高温告警"},{"id":4,"propertyName":"alarm_title","propertyLabel":"告警标题","label":"包含","op":"contains","filterValue":"高温告警","filterType":null,"filterName":"高温告警"}]}}'
jsonObj = json.loads(jsonString)
id = jsonObj.get("propertyFilterRule")['id']
print(id)
isSimple = jsonObj.get("propertyFilterRule")['isSimple']
print(isSimple)
simpleRelationOp = jsonObj.get("propertyFilterRule")['simpleRelationOp']
print(simpleRelationOp)
complexRelationOp = jsonObj.get("propertyFilterRule")["complexRelationOp"]
print(complexRelationOp)
x = jsonObj.get("propertyFilterRule")["x"]
print(x)
y = jsonObj.get("propertyFilterRule")["y"]
print(y)
present = jsonObj.get("propertyFilterRule")["present"]
print(present)

id0 = jsonObj.get("propertyFilterRule")["filterList"][0]['id']
print(id0)
propertyName0 = jsonObj.get("propertyFilterRule")["filterList"][0]['propertyName']
print(propertyName0)
propertyLabel0 = jsonObj.get("propertyFilterRule")["filterList"][0]['propertyLabel']
print(propertyLabel0)
label0 = jsonObj.get("propertyFilterRule")["filterList"][0]['label']
print(label0)
op0 = jsonObj.get("propertyFilterRule")["filterList"][0]['op']
print(op0)
filterValue0 = jsonObj.get("propertyFilterRule")["filterList"][0]['filterValue']
print(filterValue0)
filterType0 = jsonObj.get("propertyFilterRule")["filterList"][0]['filterType']
print(filterType0)
filterName0 = jsonObj.get("propertyFilterRule")["filterList"][0]['filterName']
print(filterName0)

id1 = jsonObj.get("propertyFilterRule")["filterList"][1]['id']
print(id1)
propertyName1 = jsonObj.get("propertyFilterRule")["filterList"][1]['propertyName']
print(propertyName1)
propertyLabel1 = jsonObj.get("propertyFilterRule")["filterList"][1]['propertyLabel']
print(propertyLabel1)
label1 = jsonObj.get("propertyFilterRule")["filterList"][1]['label']
print(label1)
op1 = jsonObj.get("propertyFilterRule")["filterList"][1]['op']
print(op1)
filterValue1 = jsonObj.get("propertyFilterRule")["filterList"][1]['filterValue']
print(filterValue1)
filterType1 = jsonObj.get("propertyFilterRule")["filterList"][1]['filterType']
print(filterType1)
filterName1 = jsonObj.get("propertyFilterRule")["filterList"][1]['filterName']
print(filterName1)

id2 = jsonObj.get("propertyFilterRule")["filterList"][2]['id']
print(id2)
propertyName2 = jsonObj.get("propertyFilterRule")["filterList"][2]['propertyName']
print(propertyName2)
propertyLabel2 = jsonObj.get("propertyFilterRule")["filterList"][2]['propertyLabel']
print(propertyLabel2)
label2 = jsonObj.get("propertyFilterRule")["filterList"][2]['label']
print(label2)
op2 = jsonObj.get("propertyFilterRule")["filterList"][2]['op']
print(op2)
filterValue2 = jsonObj.get("propertyFilterRule")["filterList"][2]['filterValue']
print(filterValue2)
filterType2 = jsonObj.get("propertyFilterRule")["filterList"][2]['filterType']
print(filterType2)
filterName2 = jsonObj.get("propertyFilterRule")["filterList"][2]['filterName']
print(filterName2)

id3 = jsonObj.get("propertyFilterRule")["filterList"][3]['id']
print(id3)
propertyName3 = jsonObj.get("propertyFilterRule")["filterList"][3]['propertyName']
print(propertyName3)
propertyLabel3 = jsonObj.get("propertyFilterRule")["filterList"][3]['propertyLabel']
print(propertyLabel3)
label3 = jsonObj.get("propertyFilterRule")["filterList"][3]['label']
print(label3)
op3 = jsonObj.get("propertyFilterRule")["filterList"][3]['op']
print(op3)
filterValue3 = jsonObj.get("propertyFilterRule")["filterList"][3]['filterValue']
print(filterValue3)
filterType3 = jsonObj.get("propertyFilterRule")["filterList"][3]['filterType']
print(filterType3)
filterName3 = jsonObj.get("propertyFilterRule")["filterList"][3]['filterName']
print(filterName3)

header = ['id','isSimple','simpleRelationOp','complexRelationOp','x','y','present','id0','propertyName0','propertyLabel0','label0','op0','filterValue0','filterType0','filterName0','id1','propertyName1','propertyLabel1','label1','op1','filterValue1','filterType1','filterName1','id2','propertyName2','propertyLabel2','label2','op2','filterValue2','filterType2','filterName2','id3','propertyName3','propertyLabel3','label3','op3','filterValue3','filterType3','filterName3']
datawindow4 = [id,isSimple,simpleRelationOp,complexRelationOp,x,y,present,id0,propertyName0,propertyLabel0,label0,op0,filterValue0,filterType0,filterName0,id1,propertyName1,propertyLabel1,label1,op1,filterValue1,filterType1,filterName1,id2,propertyName2,propertyLabel2,label2,op2,filterValue2,filterType2,filterName2,id3,propertyName3,propertyLabel3,label3,op3,filterValue3,filterType3,filterName3]

with open('d:\\new.csv', 'w') as f:
    writer = csv.writer(f, delimiter='|')
    writer.writerow(header)
    writer.writerow(datawindow4)

2、解析xml 文件,按标准存入csv

#xml格式
'''
<?xml version="1.0" encoding="UTF-8"?>
<DataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:/Users/Administrator/Desktop/schema.xsd">
	<FileHeader>
		<TimeStamp>2022-07-20T12:16:49</TimeStamp>
		<TimeZone>UTC+8</TimeZone>
		<VendorName>FH</VendorName>
		<ElementType>PON</ElementType>
		<CmVersion>V1.0.0</CmVersion>
	</FileHeader>
	<Objects>
		<ObjectType>VLN</ObjectType>
		<FieldName>
			<N i="1">nermUID</N>
			<N i="2">portrmUID</N>
			<N i="3">vlanId</N>
			<N i="4">vlanMode</N>
			<N i="5">mvlanFlag</N>
			<N i="6">mvlanPri</N>
			<N i="7">service</N>
		</FieldName>
		<FieldValue>
			<Object rmUID="5101FHCS1VLN004A10021L0903">
				<V i="1">5101FHCS1OLT004A1</V>
				<V i="2">5101FHCS1PRT004A1009L03</V>
				<V i="3">21</V>
				<V i="4">SINGLE</V>
				<V i="5">0</V>
				<V i="6">--</V>
				<V i="7">HSI</V>
			</Object>
			<Object rmUID="5101FHCS1VLN004A10021A0000">
				<V i="1">5101FHCS1OLT004A1</V>
				<V i="2">--</V>
				<V i="3">21</V>
				<V i="4">SINGLE</V>
				<V i="5">0</V>
				<V i="6">--</V>
				<V i="7">HSI</V>
			</Object>
			<Object rmUID="5101FHCS1VLN004A10022L0903">
				<V i="1">5101FHCS1OLT004A1</V>
				<V i="2">5101FHCS1PRT004A1009L03</V>
				<V i="3">22</V>
				<V i="4">SINGLE</V>
				<V i="5">0</V>
				<V i="6">--</V>
				<V i="7">HSI</V>
			</Object>
		</FieldValue>
	</Objects>
</DataFile>

'''

# -*- coding: utf-8 -*-
"""
    @Author  : sunbo
    @Time    : 2022/7/26 0024 上午 9:19
    @Comment :
"""
import csv
from xml.dom.minidom import parse
import os
import time
date_ = time.strftime("%Y%m%d",time.localtime())
dst_file_path = "D:\\"+date_+ "\CM"
if not os.path.exists(dst_file_path):
 	os.makedirs(dst_file_path)
else:
  	print(dst_file_path)

def readXML():
	domTree = parse("CM-PON-VLN-A1-V1.0.0-20220720120000-002.xml")
	# 文档根元素
	rootNode = domTree.documentElement
	print(rootNode.nodeName)
	table_heads = rootNode.getElementsByTagName("FieldName")
	print(len(table_heads))

	print("****所有表头信息****:",table_heads)
	for table_head in table_heads:
		name = table_head.getElementsByTagName("N")[0]
		v_nermuid = name.childNodes[0].data
		name = table_head.getElementsByTagName("N")[1]
		v_portrmuid = name.childNodes[0].data
		name = table_head.getElementsByTagName("N")[2]
		v_vlanid = name.childNodes[0].data
		name = table_head.getElementsByTagName("N")[3]
		v_lanmode = name.childNodes[0].data
		name = table_head.getElementsByTagName("N")[4]
		v_mvlanflag = name.childNodes[0].data
		name = table_head.getElementsByTagName("N")[5]
		v_mvlanpri = name.childNodes[0].data
		name = table_head.getElementsByTagName("N")[6]
		v_service = name.childNodes[0].data
	headers = [v_nermuid,v_portrmuid,v_vlanid,v_lanmode,v_mvlanflag,v_mvlanpri,v_service]
	with open(dst_file_path+"\\"+"new"+date_+".csv",'w',newline="") as f:
		writer = csv.writer(f,delimiter = '|')
		writer.writerow(headers)

	objects = rootNode.getElementsByTagName("Object")
	print("****所有记录信息****")
	for object in objects:
		if object.hasAttribute("rmUID"):
			v_nermuid_value = object.getAttribute("rmUID")
			name = object.getElementsByTagName("V")[0]
			v_portrmuid_value = name.childNodes[0].data
			name = object.getElementsByTagName("V")[1]
			v_vlanid_value = name.childNodes[0].data
			name = object.getElementsByTagName("V")[2]
			v_lanmode_value = name.childNodes[0].data
			name = object.getElementsByTagName("V")[3]
			v_mvlanflag_value = name.childNodes[0].data
			name = object.getElementsByTagName("V")[4]
			v_mvlanpri_value =name.childNodes[0].data
			name = object.getElementsByTagName("V")[5]
			v_service_value = name.childNodes[0].data
			data_value = [v_nermuid_value,v_portrmuid_value,v_vlanid_value,
						  v_lanmode_value,v_mvlanflag_value,v_mvlanpri_value,v_service_value]
			with open(dst_file_path+"\\"+"new"+date_+".csv", "a+",newline="") as f:
				writer = csv.writer(f, delimiter='|')
				writer.writerow(data_value)

if __name__ == '__main__':
	readXML()
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值