使用API
in Web Crawler 访问: 690 次 with 0 comment

使用API

in Web Crawler with 0 comment

K0XfmM4xHNE.jpg

使用API

API:它们为不同的应用提供了方便友好的接口。不同的开发者用不同的架构,甚至不同的语言编写软件都没问题——因为 API 设计的目的就是要成为一种通用语言,让不同的软件进行信息共享。

API概述

API 之所以叫 API 而不是叫网站的原因,其实是首先 API 请求使用非常严谨的语法,其次 API 用 JSON 或 XML 格式表示数据,而不是HTML 格式。

http://api.ipstack.com/140.114.123.137?access_key=apikeys

API通用规则

方法

GET

POST

PUT

DELETE

验证

通常 API 验证的方法都是用类似令牌(token)的方式调用,每次 API 调用都会把令牌传
递到服务器上。这种令牌要么是用户注册的时候分配给用户,要么就是在用户调用的时候才提供,可能是长期固定的值,也可能是频繁变化的,通过服务器对用户名和密码的组合处理后生成。

服务器响应

当使用 GET 请求获取数据时,用URL 路径描述你要获取的数据范围,查询参数可以作为过滤器或附加请求使用。

解析JSON数据

import json
from urllib.request import urlopen

def get_country(ip_address):
    response = urlopen("http://api.ipstack.com/" + ip_address + "?access_key=apikeys").read().decode('utf-8')
    response_json = json.loads(response)
    return response_json.get("country_name")

print(get_country("50.78.253.58"))

Python 使用了一种更加灵活的方式,把 JSON 转换成字典,JSON 数组转换成列表,JSON 字符串转换成 Python 字符串。通过这种方式,就可以让 JSON 的获取和操作变得非常简单。

回到主题

如果你用 API 作为唯一的数据源,那么你最多就是复制别人数据库里的数据,不过都是些已经公布过的“黄花菜”。真正有意思的事情,是把多个数据源组合成新的形式,或者把 API 作为一种工具,从全新的视角对采集到的数据进行解释。

from urllib.request import urlopen
from bs4 import BeautifulSoup
import datetime
import random
import re

random.seed(datetime.datetime.now())

def get_links(article_url):
    html =  urlopen("http://en.wikipedia.org" + article_url)
    bs_obj = BeautifulSoup(html,"xml")
    return bs_obj.find("div", {"id":"bodyContent"}).findAll("a",
                       href=re.compile("^(/wiki/)((?!:).)*$"))

def get_history_ips(page_url):
    # 编辑历史页面URL链接格式是:
    # http://en.wikipedia.org/w/index.php?title=Title_in_URL&action=history
    #/wiki/替换为空
    page_url = page_url.replace("/wiki/", "")
    history_url = "http://en.wikipedia.org/w/index.php?title=" + page_url + "&action=history"
    print("history url is:" + history_url)
    html = urlopen(history_url)
    bs_obj = BeautifulSoup(html,"xml")

    # 找出class属性是"mw-anonuserlink"的链接
    # 它们用IP地址代替用户名
    ip_addresses = bs_obj.findAll("a", {"class":"mw-userlink mw-anonuserlink"})
    address_list = set()
    for ip_address in ip_addresses:
        address_list.add(ip_address.get_text())
    return address_list

links = get_links("/wiki/Python_(programming_language)")

while(len(links)>0):
    for link in links:
        print("-------------------")
        history_ips = get_history_ips(link.attrs['href'])
        for history_ip in history_ips:
            print(history_ip)
    new_link = links[random.randint(0,len(links)-1)].attrs['href']
    links = get_links(new_link)

首先获取起始词条连接的所有词条的编辑历史,然后,随机选择一个词条作为起始点,再获取这个页面连接的所有词条的编辑历史。重复这个过程直到页面没有连接维基词条为止。

from urllib.request import urlopen
from bs4 import BeautifulSoup
import datetime
import random
import re
import json

random.seed(datetime.datetime.now())

def get_links(article_url):
    html =  urlopen("http://en.wikipedia.org" + article_url)
    bs_obj = BeautifulSoup(html,"xml")
    return bs_obj.find("div", {"id":"bodyContent"}).findAll("a",
                       href=re.compile("^(/wiki/)((?!:).)*$"))

def get_history_ips(page_url):
    # 编辑历史页面URL链接格式是:
    # http://en.wikipedia.org/w/index.php?title=Title_in_URL&action=history
    #/wiki/替换为空
    page_url = page_url.replace("/wiki/", "")
    history_url = "http://en.wikipedia.org/w/index.php?title=" + page_url + "&action=history"
    print("history url is:" + history_url)
    html = urlopen(history_url)
    bs_obj = BeautifulSoup(html,"xml")

    # 找出class属性是"mw-anonuserlink"的链接
    # 它们用IP地址代替用户名
    ip_addresses = bs_obj.findAll("a", {"class":"mw-userlink mw-anonuserlink"})
    address_list = set()
    for ip_address in ip_addresses:
        address_list.add(ip_address.get_text())
    return address_list

def get_country(ip_address):
    try:
        response = urlopen("http://api.ipstack.com/" + ip_address + "?access_key=apikeys").read().decode('utf-8')
    except HTTPError:
        return None
    response_json = json.loads(response)
    return response_json.get("country_code")


links = get_links("/wiki/Python_(programming_language)")

while(len(links)>0):
    for link in links:
        print("-------------------")
        history_ips = get_history_ips(link.attrs['href'])
        for history_ip in history_ips:
            country = get_country(history_ip)
            if country is not None:
                print(history_ip + " is from " + country)
    new_link = links[random.randint(0,len(links)-1)].attrs['href']
    links = get_links(new_link)
Responses