python爬取免費優質IP歸屬地查詢接口
具體不表,我今天要做的工作就是: 需要將數據庫中大量ip查詢出起歸屬地
剛開始感覺好簡單啊,畢竟只需要從百度找個免費接口然后來個python腳本跑一晚上就ok了嘛~但是,網上免費接口要么限制訪問頻率(淘寶的),要么限制訪問次數(百度及其他)
沒轍了,從百度找到了幾個在線查詢的接口,要么不夠准確(或者說她們的數據庫太舊了),要么就是速度太慢了,跟限制訪問似的(沒辦法,小規模人家的服務器的確不夠好)
於是乎就想到了百度首頁的ip接口,就這貨:
為了防止泄露隱私,其中ip地址信息已經在控制台稍作修改
隨便輸入一個ip,點擊查詢
沒想到,百度的接口竟然就這么暴露出來了,如此簡單,試試能不能直接用
ip00.py
from pprint import pprint
import requests
res = requests.get(
'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=112.53.65.12&co=&resource_id=6006&t=1551419352431&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb=jQuery110200929818675063574_1551418734860&_=1551418734868')
pprint(res.text)
返回結果:
('/**/jQuery110200929818675063574_1551418734860({"status":"0","t":"1551419352431","set_cache_time":"","data":[{"location":"山東省青島市 '
'移動","titlecont":"IP地址查詢","origip":"112.53.65.12","origipquery":"112.53.65.12","showlamp":"1","showLikeShare":1,"shareImage":1,"ExtendedLocation":"","OriginQuery":"112.53.65.12","tplt":"ip","resourceid":"6006","fetchkey":"112.53.65.12","appinfo":"","role_id":0,"disp_type":0}]});')
與瀏覽器訪問返回結果一樣,這個太出乎意料了,好吧,b廠還是留了點情面的,可是他們家的接口只能按年來買,大概要999RMB/年
再測試一下換個 ip 地址繼續查詢還能不能查到結果(防止后面的數據是加密的)
這個呢,其實最好的辦法是在瀏覽器中進行測試,換個ip看一下控制台的url會不會有變化(主要是后面的參數),可能會存在加密數據,其實這個我測試了,會有一個參數變化 ,但是我重復提交時沒發生改變一樣能夠請求數據,幾乎就可以說明這個參數是迷惑用的(也可能是時間戳吧,我忘了具體什么參數了.時間戳的話就更好了,為了防止瀏覽器有緩存的)
ip01.py
from pprint import pprint
import requests
res = requests.get(
'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=112.53.54.12&co=&resource_id=6006&t=1551419352431&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb=jQuery110200929818675063574_1551418734860&_=1551418734868')
pprint(res.text)
返回結果:
('/**/jQuery110200929818675063574_1551418734860({"status":"0","t":"1551419352431","set_cache_time":"","data":[{"location":"廣東省 '
'移動","titlecont":"IP地址查詢","origip":"112.53.54.12","origipquery":"112.53.54.12","showlamp":"1","showLikeShare":1,"shareImage":1,"ExtendedLocation":"","OriginQuery":"112.53.54.12","tplt":"ip","resourceid":"6006","fetchkey":"112.53.54.12","appinfo":"","role_id":0,"disp_type":0}]});')
ok,數據更換ip也是沒有問題的,也不需要偽裝agent
那么我們來嘗試一下訪問頻率有沒有限制:
這里先為大家介紹一個庫:faker
這是一個python造假用的庫,可以生成很多測試數據,姓名地址電話等等信息
這里推薦一位陌生老哥的博客:https://www.cnblogs.com/blueteer/p/10277725.html,如果不知道這個庫,可以看一眼下面的 小demo:
faker_test.py
from faker import Faker
f = Faker('zh-CN')
print(f.ipv4())
返回結果:
101.208.5.200
這段代碼就這點功能,就是可以生成隨機ip地址
ip02.py
from pprint import pprint
import requests
from faker import Faker
f = Faker('zh-CN')
for i in range(100):
ip = f.ipv4()
res = requests.get(
'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=' + ip +
'&co=&resource_id=6006&t'
'=1551419352431&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb'
'=jQuery110200929818675063574_1551418734860&_=1551418734868')
pprint(res.text)
這里稍微整理了一下url,就是換了個行而已
返回結果(太多了 ,截個圖意思意思)
速度挺快,待會兒再測試一下它的耗時到底有多少
數據雜亂不好整理,直接來個簡單粗暴的分割字符串吧:
稍作修改后:
ip03.py
import requests
from faker import Faker
f = Faker('zh-CN')
for i in range(100):
ip = f.ipv4()
res = requests.get(
'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=' + ip +
'&co=&resource_id=6006&t'
'=1551419352431&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb'
'=jQuery110200929818675063574_1551418734860&_=1551418734868')
text = res.text
location = text.split('location":"')[1].split('","titlecont')[0]
print(location)
嚇死我了,剛才斷網了,我還以為百度的這條路只能走這么遠了呢,畢竟我上午已經弄了不少數據了,下午就不行的話,我這一上午豈不是白瞎了
返回結果
澳大利亞
澳大利亞
廣東省 電信
韓國
美國
美國
美國
比利時
美國
美國
...后面的不發了,太長了
最后,來計個時
ip04.py
from time import time
import requests
from faker import Faker
# 獲取當前秒級時間戳
t1 = int(time())
f = Faker('zh-CN')
for i in range(100):
ip = f.ipv4()
res = requests.get(
'https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=' + ip +
'&co=&resource_id=6006&t'
'=1551419352431&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb'
'=jQuery110200929818675063574_1551418734860&_=1551418734868')
text = res.text
location = text.split('location":"')[1].split('","titlecont')[0]
print(location)
t2 = int(time())
print(t2 - t1)
返回結果:
...
美國
美國
美國
荷蘭
美國
美國
澳大利亞
澳大利亞
19
還不錯吧,100個耗時19秒,想要更快可以試試java或者多線程吧,反證我就用這一次,而且也不趕時間,估計今晚就把我那些數據搞定了
最后娛樂一下,縮減一下代碼行數(計時就去掉了,反正對我也沒什么實際用途)
import requests;from faker import Faker;f = Faker('zh-CN');print([requests.get('https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=' + f.ipv4() +'&resource_id=6006&_='+str(i)).text.split('ation":"')[1].split('","tit')[0] for i in range(10)])
這里主要是精簡了一部分url,不知道修改后還好不好使了
python一行代碼(251字)搞定爬取百度ip接口並實現查詢數據(歡呼)
好險這字數,還好沒再刪東西,哈哈哈,別整這些沒用的了