最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

調(diào)用無文檔說明的?Web?API過程描述

 更新時(shí)間:2022年03月22日 16:50:36   作者:Julia?Evans  
這篇文章主要為大家介紹了調(diào)用無文檔說明的Web?API過程描述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>

大家好!幾天前我寫了篇 小型的個(gè)人程序 的文章,里面提到了調(diào)用沒有文檔說明的“秘密” API 很有意思,你需要從你的瀏覽器中把 cookies 復(fù)制出來才能訪問。

有些讀者問如何實(shí)現(xiàn),因此我打算詳細(xì)描述下,其實(shí)過程很簡單。我們還會(huì)談?wù)勗谡{(diào)用沒有文檔說明的 API 時(shí),可能會(huì)遇到的錯(cuò)誤和道德問題。

我們用谷歌 Hangouts 舉例。我之所以選擇它,并不是因?yàn)檫@個(gè)例子最有用(我認(rèn)為官方的 API 更實(shí)用),而是因?yàn)樵谶@個(gè)場景中更有用的網(wǎng)站很多是小網(wǎng)站,而小網(wǎng)站的 API 一旦被濫用,受到的傷害會(huì)更大。因此我們使用谷歌 Hangouts,因?yàn)槲?100% 肯定谷歌論壇可以抵御這種試探行為。

我們現(xiàn)在開始!

第一步:打開開發(fā)者工具,找一個(gè) JSON 響應(yīng)

我瀏覽了 https://hangouts.google.com,在 Firefox 的開發(fā)者工具中打開“網(wǎng)絡(luò)Network”標(biāo)簽,找到一個(gè) JSON 響應(yīng)。你也可以使用 Chrome 的開發(fā)者工具。

打開之后界面如下圖:

找到其中一條 “類型Type” 列顯示為 json 的請(qǐng)求。

為了找一條感興趣的請(qǐng)求,我找了好一會(huì)兒,突然我找到一條 “people” 的端點(diǎn),看起來是返回我們的聯(lián)系人信息。聽起來很有意思,我們來看一下。

第二步:復(fù)制為 cURL

下一步,我在感興趣的請(qǐng)求上右鍵,點(diǎn)擊 “復(fù)制Copy” -> “復(fù)制為 cURLCopy as cURL”。

然后我把 curl 命令粘貼到終端并運(yùn)行。下面是運(yùn)行結(jié)果:

$ curl 'https://people-pa.clients6.google.com/v2/people/?key=REDACTED' -X POST ........ (省略了大量請(qǐng)求標(biāo)頭)
Warning: Binary output can mess up your terminal. Use "--output -" to tell 
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: <FILE>" to save to a file.

你可能會(huì)想 —— 很奇怪,“二進(jìn)制的輸出在你的終端上無法正常顯示” 是什么錯(cuò)誤?原因是,瀏覽器默認(rèn)情況下發(fā)給服務(wù)器的請(qǐng)求頭中有 Accept-Encoding: gzip, deflate 參數(shù),會(huì)把輸出結(jié)果進(jìn)行壓縮。

我們可以通過管道把輸出傳遞給 gunzip 來解壓,但是我們發(fā)現(xiàn)不帶這個(gè)參數(shù)進(jìn)行請(qǐng)求會(huì)更簡單。因此我們?nèi)サ粢恍┎幌嚓P(guān)的請(qǐng)求頭。

第三步:去掉不相關(guān)的請(qǐng)求頭

下面是我從瀏覽器獲得的完整 curl 命令。有很多行!我用反斜杠(\)把請(qǐng)求分開,這樣每個(gè)請(qǐng)求頭占一行,看起來更清晰:

curl 'https://people-pa.clients6.google.com/v2/people/?key=REDACTED' \
-X POST \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0' \
-H 'Accept: */*' \
-H 'Accept-Language: en' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'X-HTTP-Method-Override: GET' \
-H 'Authorization: SAPISIDHASH REDACTED' \
-H 'Cookie: REDACTED'
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'X-Goog-AuthUser: 0' \
-H 'Origin: https://hangouts.google.com' \
-H 'Connection: keep-alive' \
-H 'Referer: https://hangouts.google.com/' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-site' \
-H 'Sec-GPC: 1' \
-H 'DNT: 1' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache' \
-H 'TE: trailers' \
--data-raw 'personId=101777723309&personId=1175339043204&personId=1115266537043&personId=116731406166&extensionSet.extensionNames=HANGOUTS_ADDITIONAL_DATA&extensionSet.extensionNames=HANGOUTS_OFF_NETWORK_GAIA_GET&extensionSet.extensionNames=HANGOUTS_PHONE_DATA&includedProfileStates=ADMIN_BLOCKED&includedProfileStates=DELETED&includedProfileStates=PRIVATE_PROFILE&mergedPersonSourceOptions.includeAffinity=CHAT_AUTOCOMPLETE&coreIdParams.useRealtimeNotificationExpandedAcls=true&requestMask.includeField.paths=person.email&requestMask.includeField.paths=person.gender&requestMask.includeField.paths=person.in_app_reachability&requestMask.includeField.paths=person.metadata&requestMask.includeField.paths=person.name&requestMask.includeField.paths=person.phone&requestMask.includeField.paths=person.photo&requestMask.includeField.paths=person.read_only_profile_info&requestMask.includeField.paths=person.organization&requestMask.includeField.paths=person.location&requestMask.includeField.paths=person.cover_photo&requestMask.includeContainer=PROFILE&requestMask.includeContainer=DOMAIN_PROFILE&requestMask.includeContainer=CONTACT&key=REDACTED'

第一眼看起來內(nèi)容有很多,但是現(xiàn)在你不需要考慮每一行是什么意思。你只需要把不相關(guān)的行刪掉就可以了。

我通常通過刪掉某行查看是否有錯(cuò)誤來驗(yàn)證該行是不是可以刪除 —— 只要請(qǐng)求沒有錯(cuò)誤就一直刪請(qǐng)求頭。通常情況下,你可以刪掉 Accept*Referer、Sec-*、DNT、User-Agent 和緩存相關(guān)的頭。

在這個(gè)例子中,我把請(qǐng)求刪成下面的樣子:

curl 'https://people-pa.clients6.google.com/v2/people/?key=REDACTED' \
-X POST \
-H 'Authorization: SAPISIDHASH REDACTED' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Origin: https://hangouts.google.com' \
-H 'Cookie: REDACTED'\
--data-raw 'personId=101777723309&personId=1175339043204&personId=1115266537043&personId=116731406166&extensionSet.extensionNames=HANGOUTS_ADDITIONAL_DATA&extensionSet.extensionNames=HANGOUTS_OFF_NETWORK_GAIA_GET&extensionSet.extensionNames=HANGOUTS_PHONE_DATA&includedProfileStates=ADMIN_BLOCKED&includedProfileStates=DELETED&includedProfileStates=PRIVATE_PROFILE&mergedPersonSourceOptions.includeAffinity=CHAT_AUTOCOMPLETE&coreIdParams.useRealtimeNotificationExpandedAcls=true&requestMask.includeField.paths=person.email&requestMask.includeField.paths=person.gender&requestMask.includeField.paths=person.in_app_reachability&requestMask.includeField.paths=person.metadata&requestMask.includeField.paths=person.name&requestMask.includeField.paths=person.phone&requestMask.includeField.paths=person.photo&requestMask.includeField.paths=person.read_only_profile_info&requestMask.includeField.paths=person.organization&requestMask.includeField.paths=person.location&requestMask.includeField.paths=person.cover_photo&requestMask.includeContainer=PROFILE&requestMask.includeContainer=DOMAIN_PROFILE&requestMask.includeContainer=CONTACT&key=REDACTED'

這樣我只需要 4 個(gè)請(qǐng)求頭:Authorization、Content-Type、Origin 和 Cookie。這樣容易管理得多。

第四步:在 Python 中發(fā)請(qǐng)求

現(xiàn)在我們知道了我們需要哪些請(qǐng)求頭,我們可以把 curl 命令翻譯進(jìn) Python 程序!這部分是相當(dāng)機(jī)械化的過程,目標(biāo)僅僅是用 Python 發(fā)送與 cUrl 相同的數(shù)據(jù)。

下面是代碼實(shí)例。我們使用 Python 的 requests 包實(shí)現(xiàn)了與前面 curl 命令相同的功能。我把整個(gè)長請(qǐng)求分解成了元組的數(shù)組,以便看起來更簡潔。

import requests
import urllib
data = [
    ('personId','101777723'), # I redacted these IDs a bit too
    ('personId','117533904'),
    ('personId','111526653'),
    ('personId','116731406'),
    ('extensionSet.extensionNames','HANGOUTS_ADDITIONAL_DATA'),
    ('extensionSet.extensionNames','HANGOUTS_OFF_NETWORK_GAIA_GET'),
    ('extensionSet.extensionNames','HANGOUTS_PHONE_DATA'),
    ('includedProfileStates','ADMIN_BLOCKED'),
    ('includedProfileStates','DELETED'),
    ('includedProfileStates','PRIVATE_PROFILE'),
    ('mergedPersonSourceOptions.includeAffinity','CHAT_AUTOCOMPLETE'),
    ('coreIdParams.useRealtimeNotificationExpandedAcls','true'),
    ('requestMask.includeField.paths','person.email'),
    ('requestMask.includeField.paths','person.gender'),
    ('requestMask.includeField.paths','person.in_app_reachability'),
    ('requestMask.includeField.paths','person.metadata'),
    ('requestMask.includeField.paths','person.name'),
    ('requestMask.includeField.paths','person.phone'),
    ('requestMask.includeField.paths','person.photo'),
    ('requestMask.includeField.paths','person.read_only_profile_info'),
    ('requestMask.includeField.paths','person.organization'),
    ('requestMask.includeField.paths','person.location'),
    ('requestMask.includeField.paths','person.cover_photo'),
    ('requestMask.includeContainer','PROFILE'),
    ('requestMask.includeContainer','DOMAIN_PROFILE'),
    ('requestMask.includeContainer','CONTACT'),
    ('key','REDACTED')
]
response = requests.post('https://people-pa.clients6.google.com/v2/people/?key=REDACTED',
    headers={
        'X-HTTP-Method-Override': 'GET',
        'Authorization': 'SAPISIDHASH REDACTED',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Origin': 'https://hangouts.google.com',
        'Cookie': 'REDACTED',
    },
    data=urllib.parse.urlencode(data),
)
print(response.text)

我執(zhí)行這個(gè)程序后正常運(yùn)行 —— 輸出了一堆 JSON 數(shù)據(jù)!太棒了!

你會(huì)注意到有些地方我用 REDACTED 代替了,因?yàn)槿绻野言紨?shù)據(jù)列出來你就可以用我的賬號(hào)來訪問谷歌論壇了,這就很不好了。

運(yùn)行結(jié)束

現(xiàn)在我可以隨意修改 Python 程序,比如傳入不同的參數(shù),或解析結(jié)果等。

我不打算用它來做其他有意思的事了,因?yàn)槲覊焊鶎?duì)這個(gè) API 沒興趣,我只是用它來闡述請(qǐng)求 API 的過程。

但是你確實(shí)可以對(duì)返回的一堆 JSON 做一些處理。

curlconverter 看起來很強(qiáng)大

有人評(píng)論說可以使用 https://curlconverter.com/ 自動(dòng)把 curl 轉(zhuǎn)換成 Python(和一些其他的語言!),這看起來很神奇 —— 我都是手動(dòng)轉(zhuǎn)的。我在這個(gè)例子里使用了它,看起來一切正常。

追蹤 API 的處理過程并不容易

我不打算夸大追蹤 API 處理過程的難度 —— API 的處理過程并不明顯!我也不知道傳給這個(gè)谷歌論壇 API 的一堆參數(shù)都是做什么的!

但是有一些參數(shù)看起來很直觀,比如 

requestMask.includeField.paths=person.email 

可能表示“包含每個(gè)人的郵件地址”。因此我只關(guān)心我能看懂的參數(shù),不關(guān)心看不懂的。

(理論上)適用于所有場景

可能有人質(zhì)疑 —— 這個(gè)方法適用于所有場景嗎?

答案是肯定的 —— 瀏覽器不是魔法!瀏覽器發(fā)送給你的服務(wù)器的所有信息都是 HTTP 請(qǐng)求。因此如果我復(fù)制了瀏覽器發(fā)送的所有的 HTTP 請(qǐng)求頭,那么后端就會(huì)認(rèn)為請(qǐng)求是從我的瀏覽器發(fā)出的,而不是用 Python 程序發(fā)出的。

當(dāng)然,我們?nèi)サ袅艘恍g覽器發(fā)送的請(qǐng)求頭,因此理論上后端是可以識(shí)別出來請(qǐng)求是從瀏覽器還是 Python 程序發(fā)出的,但是它們通常不會(huì)檢查。

這里有一些對(duì)讀者的告誡 —— 一些谷歌服務(wù)的后端會(huì)通過令人難以理解(對(duì)我來說是)方式跟前端通信,因此即使理論上你可以模擬前端的請(qǐng)求,但實(shí)際上可能行不通。可能會(huì)遭受更多攻擊的大型 API 會(huì)有更多的保護(hù)措施。

我們已經(jīng)知道了如何調(diào)用沒有文檔說明的 API?,F(xiàn)在我們?cè)賮砹牧目赡苡龅降膯栴}。

問題 1:會(huì)話 cookie 過期

一個(gè)大問題是我用我的谷歌會(huì)話 cookie 作為身份認(rèn)證,因此當(dāng)我的瀏覽器會(huì)話過期后,這個(gè)腳本就不能用了。

這意味著這種方式不能長久使用(我寧愿調(diào)一個(gè)真正的 API),但是如果我只是要一次性快速抓取一小組數(shù)據(jù),那么可以使用它。

問題 2:濫用

如果我正在請(qǐng)求一個(gè)小網(wǎng)站,那么我的 Python 腳本可能會(huì)把服務(wù)打垮,因?yàn)檎?qǐng)求數(shù)超出了它們的處理能力。因此我請(qǐng)求時(shí)盡量謹(jǐn)慎,盡量不過快地發(fā)送大量請(qǐng)求。

這尤其重要,因?yàn)闆]有官方 API 的網(wǎng)站往往是些小網(wǎng)站且沒有足夠的資源。

很明顯在這個(gè)例子中這不是問題 —— 我認(rèn)為在寫這篇文章的過程我一共向谷歌論壇的后端發(fā)送了 20 次請(qǐng)求,他們肯定可以處理。

如果你用自己的賬號(hào)身份過度訪問這個(gè) API 并導(dǎo)致了故障,那么你的賬號(hào)可能會(huì)被暫時(shí)封禁(情理之中)。

我只下載我自己的數(shù)據(jù)或公共的數(shù)據(jù) —— 我的目的不是尋找網(wǎng)站的弱點(diǎn)。

請(qǐng)記住所有人都可以訪問你沒有文檔說明的 API

我認(rèn)為本文最重要的信息并不是如何使用其他人沒有文檔說明的 API。雖然很有趣,但是也有一些限制,而且我也不會(huì)經(jīng)常這么做。

更重要的一點(diǎn)是,任何人都可以這么訪問你后端的 API!每個(gè)人都有開發(fā)者工具和網(wǎng)絡(luò)標(biāo)簽,查看你傳到后端的參數(shù)、修改它們都很容易。

因此如果一個(gè)人通過修改某些參數(shù)來獲取其他用戶的信息,這不值得提倡。我認(rèn)為提供公開 API 的大部分開發(fā)者們都知道,但是我之所以再提一次,是因?yàn)槊總€(gè)初學(xué)者都應(yīng)該了解。: )

via: https://jvns.ca/blog/2022/03/10/how-to-use-undocumented-web-apis/

以上就是調(diào)用無文檔說明的 Web API過程描述的詳細(xì)內(nèi)容,更多關(guān)于調(diào)用無文檔說明的Web API的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • jenkins配置163郵箱的操作方法

    jenkins配置163郵箱的操作方法

    Jenkins用Java語言編寫,可在Tomcat等流行的servlet容器中運(yùn)行,也可獨(dú)立運(yùn)行,這篇文章主要介紹了jenkins配置163郵箱的步驟,需要的朋友可以參考下
    2022-01-01
  • VSCode 遠(yuǎn)程登錄開發(fā)(帶免密)

    VSCode 遠(yuǎn)程登錄開發(fā)(帶免密)

    這篇文章主要介紹了VSCode 遠(yuǎn)程登錄開發(fā)(帶免密),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • IDEA 2020 設(shè)置項(xiàng)目集成git 及svn和git之間的切換問題

    IDEA 2020 設(shè)置項(xiàng)目集成git 及svn和git之間的切換問題

    這篇文章主要介紹了IDEA 2020 設(shè)置項(xiàng)目集成git 及svn和git之間的切換問題,本文通關(guān)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 前端開發(fā)工具nvim替帶VSCode的安裝配置

    前端開發(fā)工具nvim替帶VSCode的安裝配置

    這篇文章主要為大家介紹了一款前端開發(fā)工具nvim代替VSCode的配置使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Wireshark TS FTP 傳輸失敗問題解決

    Wireshark TS FTP 傳輸失敗問題解決

    這篇文章主要為大家介紹了Wireshark TS FTP 傳輸失敗問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • git log根據(jù)特定條件查詢?nèi)罩静⒔y(tǒng)計(jì)修改的代碼行數(shù)

    git log根據(jù)特定條件查詢?nèi)罩静⒔y(tǒng)計(jì)修改的代碼行數(shù)

    這篇文章主要介紹了git log根據(jù)特定條件查詢?nèi)罩静⒔y(tǒng)計(jì)修改的代碼行數(shù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Git在克隆的時(shí)候報(bào)錯(cuò)Permission denied (publickey)問題

    Git在克隆的時(shí)候報(bào)錯(cuò)Permission denied (publickey)問題

    Git克隆過程中可能會(huì)遇到“Permission denied (publickey)”錯(cuò)誤,這是因?yàn)镾SH密鑰未添加到Git服務(wù)器,解決方法包括生成SSH密鑰、將公鑰添加到Git服務(wù)器(如GitHub、GitLab或Gitee),操作完成后,通過特定命令驗(yàn)證,若設(shè)置正確,克隆操作應(yīng)成功執(zhí)行
    2024-09-09
  • git之遠(yuǎn)程代碼回滾master問題

    git之遠(yuǎn)程代碼回滾master問題

    這篇文章主要介紹了git之遠(yuǎn)程代碼回滾master問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • matlab 生成.bmp格式的文件

    matlab 生成.bmp格式的文件

    這篇文章主要介紹了matlab 生成.bmp格式的文件,本文以大小為M*N的圖片為例,說明頭文件格式和內(nèi)容。需要的朋友可以參考下
    2018-10-10
  • 頁面制作統(tǒng)一的頭尾的方法(asp+js)

    頁面制作統(tǒng)一的頭尾的方法(asp+js)

    有時(shí)候我們需要統(tǒng)一頁面的頭尾,如果不是獨(dú)立,每次要修改文件,就要所有的模板頁面都要修改增加麻煩,所以,獨(dú)立頭尾調(diào)用,就只需要修改兩個(gè)頁面就可以了。
    2009-04-04

最新評(píng)論

洪江市| 宜昌市| 柘城县| 屏东市| 漳平市| 房山区| 民勤县| 阿拉善右旗| 衡山县| 南投市| 阿勒泰市| 安庆市| 常州市| 满城县| 无为县| 岳阳市| 富裕县| 襄樊市| 呼玛县| 元氏县| 云安县| 无为县| 和硕县| 龙门县| 灵丘县| 丹寨县| 宣城市| 兰坪| 剑阁县| 曲沃县| 永和县| 保靖县| 康平县| 郁南县| 额尔古纳市| 吕梁市| 衡南县| 民丰县| 南丰县| 阿勒泰市| 望城县|