目录
5.1解析JSON数据
5.1.1JSON解析库
5.2API的使用
5.2.1 API概述
5.2.2 API验证
5.2.3 API使用前的准备
5.2.4 如何学习使用API
5.3综合案例--爬取糗事百科用户地址信息
5.3.1 爬虫思路分析
5.3.2爬虫代码分析
下面是代码测试
整式封装代码:
当决定去完成一个爬虫操作时,读者的第一反映可能就是用request库请求网页,然后从正则表达式、BeautifulSoup或Lxml中选择一个自己最熟悉的库来解析数据,进而提取数据。但有时我们并不需要那么“卖命”地写代码,因为应用变成接口(Application Programming Interface,API)可能已经为我们做好了一切。本章将对API进行概述,讲解API的使用和调用方法,并对API返回的JSON数据进行解析,左后通过API来完成一些案例。
调用API ,服务器会返回JSON格式的数据,如何从中提取有用的信息,是这小节的内容
Python语言中有解析JSON数据的标准库,可以通过下面代码来使用:
import json
不同于其他Python的解析库,JSON解析库并不是把JSON数据解析为JSON对象或JSON节点,而是把JSON数据转换为字典,JSON数组转换成列表,JSON字符串转换为Python字符串,这样便可以轻松的对JSO数据进行操作。
示例
jsonstring = '{"user_man":[{"name":"Peter"},{"name":"xiaoming"}],"user_woman":[{"name":"Anni"},{"name":"zhangsan"}]}'
import json
json_data = json.loads(jsonstring)
print(json_data.get("user_man"))
print(json_data.get("user_woman"))
print(json_data.get("user_man")[0].get("name"))
print(json_data.get("user_woman")[1].get("name"))
print(json_data["user_man"])
print(json_data["user_woman"])
print(json_data["user_man"][0]["name"])
print(json_data["user_woman"][1]["name"])
自己选择一个JSON数据解析的方法。
也许到现在我们还不知道API到底是一个多好用的东西。通过下面的讲解,我们在进行网络爬虫之前应该先考虑该网站是否有API,如果网站有API的话,不用爬虫也可以调用信息。
随着网络技术的发展,API的应用也越来越多,一些大型网站都会为自己构造API,为使用者或开发者提供便利。例如,可以通过高德地图API,进行查询路线、定位坐标等。服务各种各样,大家自行了解。
API也是通过Requests请求和服务器端的Response回应来完成一次API的调用,与我们前面的request没什么区别,API的请求使用非常严谨的语法,并且API发挥的是JSON或XML数据,而不是HTML数据
有些简单的API不需要验证操作,但现在大部分API是需要用户提交验证的。提交验证主要是为了计算API调用的费用,对于这种常见的API,如天气查询API,需要购买APIKEY作为验证才能调用API。
API的使用也很简单,就是发起GET请求,他会返回JSON或XML数据,我们利用相应的解析库进行解析便可。
(1)首先我们要去高德地图注册一个账号
(2)然后进入个人中心
(3)点击应用管理--》我的管理
(4)点击添加,自己需要什么服务就用什么服务平台,我们这里选择Web服务
输入名称、同意协议点击提交就可以了。下面是我的API,这样前期准备就做好了。
授之以鱼不如授之以渔,我们应该学会如何去用一个API,每个API都是由文档指导的。下面以高德地图API为例子。
地理/逆地理编码-API文档-开发指南-Web服务 API | 高德地图API
这里面我们能够清楚的看到,API服务地址和参数说明以及返回的参数是什么,当出现错误的时候返回的状态码和状态码对应的意义。
这个网址中明确的写明了各种指导,那么其他的API也是大同小异的。
本小节,将利用谷歌API,对糗事百科网的用户地址进行经纬度的转换
(1)本节爬取的内容为糗事百科中“热门”板块的用户地址信息,如图
幽默笑话大全_爆笑笑话_笑破你的肚子的搞笑段子 - 糗事百科糗事百科官网提供幽默笑话大全,糗百网分享的各种爆笑笑话、搞笑段子,小心笑破你的肚子,精彩搞笑笑话就在糗事百科!https://www.qiushibaike.com/text/page/1/ (2)本次爬虫我们需要在详细页中(点击用户,进入用户界面)因此我们需要先爬取进入详细页的href,进而爬取数据
(3)运用python语言把数据存入csv文本中。
from bs4 import BeautifulSoup
import requests
import json
import csv
from lxml import etree #导入库
url = 'https://www.qiushibaike.com/text/page/1/'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
}
href_list = [] #href初始化列表,后面用于存放href
url_part_1 = 'http://www.qiushibaike.com'
res = requests.get(url,headers=headers)
selector = etree.HTML(res.text)
href_infos = selector.xpath('//div[@class="article block untagged mb15 typs_hot"]')
for href_info in href_infos:
hrefs = url_part_1 + href_info.xpath('div[1]/a[2]/@href')[0] #我们的href是两部分
href_list.append(hrefs)
for href in href_list:
re = requests.get(href)
selector2 = etree.HTML(re.text)
if selector2.xpath('//div[@class="user-statis user-block"]/ul/li[5]/text()'):
#判断个人中心是否由详情界面
addresses = selector2.xpath('//div[@class="user-statis user-block"]/ul/li[5]/text()')[-1]
# print(addresses)
address = addresses.split(' · ')[0]
# print(address)
if address == '国外':
pass
else:
address = address
# print(address)
par = {'key':'8d3cb70ffdb3b65c48155903ccdb8338','address':address,}
api = 'https://restapi.amap.com/v3/geocode/geo?'
r = requests.get(api,par)
json_data = json.loads(r.text)
try:
geo = json_data['geocodes'][0]['location']
longitude = geo.split(',')[0]
latitude = geo.split(',')[1]
print(address,longitude,latitude)
except IndexError:
pass
else:
pass
from bs4 import BeautifulSoup
import requests
import json
import csv
from lxml import etree
fp = open('map2.csv','wt',newline='',encoding='utf-8')
writer = csv.writer(fp)
writer.writerow(('address','longitude','latitude'))
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
}
def get_user_url(url): #获取href函数
url_part_1 = 'http://www.qiushibaike.com'
res = requests.get(url,headers=headers)
selector = etree.HTML(res.text)
url_infos = selector.xpath('//div[@class="article block untagged mb15 typs_hot"]')
for url_info in url_infos:
hrefs = url_part_1 + href_info.xpath('div[1]/a[2]/@href')[0]
href_list.append(hrefs)
for href in href_list:
get_user_address(href)
def get_user_address(url): #获取详情地址函数
res = requests.get(url, headers=headers)
selector = etree.HTML(res.text)
if selector2.xpath('//div[@class="user-statis user-block"]/ul/li[5]/text()'):
addresses = selector2.xpath('//div[@class="user-statis user-block"]/ul/li[5]/text()')[-1]
address = addresses.split(' · ')[0]
if address == '国外':
pass
else:
address = adress
get_geo(address)
else:
pass
def get_geo(address): #获取经纬度函数
par = {'key':'8d3cb70ffdb3b65c48155903ccdb8338','address':address,}
api = 'https://restapi.amap.com/v3/geocode/geo?'
res = requests.get(api, par)
json_data = json.loads(res.text)
try:
geo = json_data['geocodes'][0]['location']
longitude = geo.split(',')[0]
latitude = geo.split(',')[1]
writer.writerow((address,longitude,latitude))
except IndexError:
pass
if __name__ == '__main__':
urls = ['http://www.qiushibaike.com/text/page/{}/'.format(str(i)) for i in range(1, 2)]
for url in urls:
get_user_url(url)
fp.close()
这里要主要API的使用是有限的。