ip地址归属地检查

最近,我接受到的任务是在CSV文件(文件中有三列,第一个ip编码,第二个ip编码,国家编码),指定国家编码,检查ip地址是否能与国家编码对应,其中需要调用API检查ip归属。做的时候遇到不少问题,做完之后学到了很多东西。

遇到的问题和解决方法

1. 如何调用API

  • API(Application Programming Interface)是应用程序接口。大多数API是基于Web标准设计的,Web API通常使用HTTP来传输信息,并提供响应信息的结构定义。这些响应消息通常都会以 XML 或 JSON 文件的形式来提供。

关于API的解释参考:https://www.redhat.com/zh/topics/api/what-are-application-programming-interfaces

url = 'https://ip.mcr.moe/?ip='
url1 = url + '1.16.0.0'
reponse = requests.get(url1)
print(reponse.text)

要提取出API返回内容的国家代码,用字典接收返回的信息

url = 'https://ip.nf/'
url1 = url + '1.16.0.0' + '.json'
print(url1)
reponse = requests.get(url1)
dic = reponse.json()
dic1 = dic.get('ip')
print(dic1.get('country'))

2. ip编码后的数字如何转化为ipv4的编码

ipv4使用32位的地址,为了方便人阅读和分析,地址采用点分十进制表示。(即四个字节分开用十进制写,中间用点隔开)

def trans(ip_num):
    buf = [0]*4
    ip = ''
    buf[0] = (ip_num >> 24) & 0xff
    buf[1] = (ip_num >> 16) & 0xff
    buf[2] = (ip_num >> 8) & 0xff
    buf[3] = (ip_num >> 0) & 0xff
    flag = 1
    for i in range(4):
        if flag == 1:
            ip += str(buf[i])
            flag = 0
        else:
            ip = ip + '.' + str(buf[i])
    return ip

3. 在python上运行数据量很大,运行很慢,怎么解决?

在装有conda环境的linux主机上后台运行python程序

  • conda上可以创建环境,激活环境
    Conda 是一个开源的软件包管理系统和环境管理系统,用于安装多个版本的软件包及其依赖关系,并在它们之间轻松切换。

1.创建环境: conda create --name tf python=3.6

2.激活环境: conda activate tf

3.查看所有虚拟环境:conda info --envs

  • 在linux后台运行程序
    使用命令 nohup python -u 你的文件 >log.log 2>&1 &
    liunx支持多用户、多任务、多进程

1.nohup(即 no hang up)为不断地执行,在界面关闭后不会停止运行

2.命令最后面的&:指后台运行,不会占据终端

具体参考:https://blog.csdn.net/weixin_42840933/article/details/85780125

3.和linux后台相关指令
jobs:查看工作进展
kill -9 进程号:杀死进程
ps -ef|grep python:终止后台运行的进程
常用命令:https://www.cnblogs.com/kaituorensheng/p/3980334.html

学到的知识

1.和python相关的细节

  • 如果程序中有中文,要在程序最开始加上# coding=UTF-8,不然用其他打开会乱码

  • 编程风格细节
    函数上面要空出两行、要在定义函数下面用三个双引号注释函数功能、注释#后面要跟一个空格

2.linux常用指令

3.linux远程传输文件scp指令

scp(secure copy):是 linux 系统下基于 ssh 登陆进行安全的远程文件拷贝命令
从本地复制到远程命令格式:
scp local_file remote_username@remote_ip:remote_folder
参考:https://www.runoob.com/linux/linux-comm-scp.html

4.Windows Power Shell

Windows PowerShell 是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能。
可以使用ssh进行远程登陆
命令:ssh username@hostip

5.linux上使用ffmpeg

小知识:多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。
如果会用到:https://eyehere.net/2019/the-complete-guide-for-using-ffmpeg-in-linux/

最后附上整个代码

# coding=UTF-8
import requests
import csv
import time


def trans(ip_num):
    """
    将ip编码转化为ipv4格式
    :param ip_num:
    :return: ip
    """
    buf = [0]*4
    ip = ''
    buf[0] = (ip_num >> 24) & 0xff
    buf[1] = (ip_num >> 16) & 0xff
    buf[2] = (ip_num >> 8) & 0xff
    buf[3] = (ip_num >> 0) & 0xff
    flag = 1
    for i in range(4):
        if flag == 1:
            ip += str(buf[i])
            flag = 0
        else:
            ip = ip + '.' + str(buf[i])
    return ip


if __name__ == '__main__':
    with open(r'/root/ipv4.CSV', 'r') as csvfile:
        reader = csv.reader(csvfile)
        list1 = [row for row in reader]     # list1存放CSV表中所有的行
    list2 = []      # list2中存放表中国家代码是KR的行
    url = ['http://ip-api.com/json/', 'https://ip.seeip.org/geoip/', 'https://ip.nf/']
    for row in list1:   # row是list1中一行,也是一个列表
        if row[2] == 'KR':
            list2.append(row)
    for row in range(len(list2)):   # 遍历list2中的每一行
        # 一行中的ip范围每个255检测一下
        for num in range(int(list2[row][0]), int(list2[row][0])+1, 255):
            list_country = []  # 存放API返回的国家
            ip = trans(num)
            flag1 = 1  # ip是否正确的标志,不正确为0
            # 每个ip在三个API中检查
            for i in range(3):
                if i == 2:
                    url1 = url[i] + ip + '.json'
                else:
                    url1 = url[i] + ip
                response = requests.get(url1)
                dic = response.json()
                # 根据三个API返回的格式不同,分别处理三个API
                # 还有一些特殊例子不同成功运行,就特殊处理
                if i == 0:
                    if dic.get('state') == 'fail':
                        list_country.append('NONE')
                    else:
                        list_country.append(dic.get('country'))
                if i == 1:
                    if dic.get('country') == None:
                        list_country.append('NONE')
                    else:
                        list_country.append(dic.get('country'))
                if i == 2:
                    if dic.get('ip').get('country') == '':
                        if dic.get('ip').get('country_code') == '':
                            list_country.append('NONE')
                        else:
                            list_country.append(dic.get('ip').get('country_code'))
                    else:
                        if dic.get('ip').get('country') == 'Korea, Republic of':
                            list_country.append('South Korea')
                        else:
                            list_country.append(dic.get('ip').get('country'))
                # 三个API检测的ip有一个不正确就加入列表
                if (i == 0 and dic.get('countryCode') != 'KR') or (i == 1 and dic.get('country_code') != 'KR') or (i == 2 and dic.get('ip').get('country_code') != 'KR'):
                    flag1 = 0
            if flag1 == 0:
                print(ip + ' ' + str(num) + ' ' + list_country[0] + ', ' + list_country[1] + ', ' + list_country[2])
        time.sleep(5)   # 运行太频繁会导致requests失败

作者:inss!w!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
原文地址:https://www.cnblogs.com/Hfolsvh/p/14762418.html