使用Selenium爬取Instagram时如何获取XHR请求中的query_hash
解决Instagram爬取中提取query_hash的问题
嘿,我明白你现在的困扰——用browsermob-proxy没拿到想要的XHR数据,还得提取那个关键的query_hash参数。其实有两个更靠谱的方法,我给你详细说说:
方法一:用Chrome DevTools Protocol(CDP)直接捕获GraphQL请求
Browsermob-proxy有时候会因为HTTPS证书或者Instagram的反爬策略丢数据,而CDP是Chrome原生的调试协议,能直接拿到浏览器里的所有网络请求,靠谱得多。
下面是具体的代码示例,用它来监听并提取query_hash:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from urllib.parse import urlparse, parse_qs # 启动Chrome并启用CDP driver = webdriver.Chrome() driver.execute_cdp_cmd('Network.enable', {}) # 定义监听请求的回调函数 def capture_query_hash(request): url = request.get('params', {}).get('request', {}).get('url', '') if 'graphql/query' in url: parsed_url = urlparse(url) query_params = parse_qs(parsed_url.query) if 'query_hash' in query_params: query_hash = query_params['query_hash'][0] print(f"抓到query_hash了:{query_hash}") # 这里可以把hash存到变量或文件里后续使用 # 绑定请求监听事件 driver.execute_cdp_cmd('Network.requestWillBeSent', {}, capture_query_hash) # 执行你的爬取流程:访问目标帖子页面 driver.get('https://www.instagram.com/p/Bi9ZURdA6Gn/') # 等待"Load More Comments"按钮出现并点击 wait = WebDriverWait(driver, 10) load_more_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), 'Load More Comments')]"))) load_more_btn.click() # 等待请求发送完成 import time time.sleep(3) # 关闭驱动 driver.quit()
这个方法会在每次GraphQL请求发送时自动捕获URL,然后提取出query_hash,完全不需要依赖第三方代理,稳定性高很多。
方法二:直接解析已获取的链接字符串
如果你已经拿到了那个包含query_hash的链接(比如你贴出来的那个),可以直接用Python的URL解析工具提取参数,代码更简单:
from urllib.parse import urlparse, parse_qs # 你获取到的目标链接 target_url = "https://www.instagram.com/graphql/query/?query_hash=33ba35000cb50da46f5b5e889df7d159&variables=%7B%22shortcode%22%3A%22Bi9ZURdA6Gn%22%2C%22first%22%3A36%2C%22after%22%3A%22AQBr-wP7U4Ykr1QRH7PYJ1a0KQivhS0Ndwae-5F8vrZ5sf1eA_Bfgn4dZ0ql0pwUf9GXPm_LPyhtCnlhH6YOHfuNstwXK9VZuUIR4zD3k24s6Q%22%7D" parsed_url = urlparse(target_url) query_params = parse_qs(parsed_url.query) query_hash = query_params['query_hash'][0] print(f"提取到的query_hash:{query_hash}")
运行这段代码就能直接得到33ba35000cb50da46f5b5e889df7d159这个值。
为什么Browsermob-proxy不好用?
Instagram现在对HTTPS的处理比较严格,browsermob-proxy的证书有时候会被浏览器拒绝,导致抓不到加密的XHR请求。而CDP是直接和Chrome通信,绕过了代理的证书问题,所以能稳定捕获所有请求。
另外要注意,Instagram的query_hash可能会不定期更新,所以动态捕获比硬编码更靠谱哦!
内容的提问来源于stack exchange,提问作者doruksahin
相关产品推荐
相关产品推荐

