首页 > 解决方案 > Python 请求库 - 从 POST 请求中抓取单独的 JSON 和 HTML 响应

问题描述

我是网络抓取、编程和 StackOverflow 的新手,所以我会尽量清楚地表达一些事情。

我正在使用 Python 请求库来尝试从本地电影院链中抓取一些信息。当我查看网络部分中的 Chrome 开发人员工具响应/预览选项卡时,我可以看到看起来非常干净和有用的 JSON:

但是,当我尝试使用请求来获取相同的信息时,我得到的是整个页面内容(html 页面上的页面)。在进一步检查 Chrome 开发人员工具中的级联后,我可以看到有两个名为 GetNowPlayingByCity 的事件:一个包含 JSON 信息,而另一个似乎是 HTML。

JSON 响应 HTML 响应

如何将两者分开并仅使用 Python 请求库获取 JSON 响应?

我已经尝试修改 requests.post 中的标头(Chrome 开发人员工具表明这是一个 post 方法)以包含“accept: application/json, text/plain, */*”,但没有看到响应有什么不同我收到了requests.post。就目前而言,我无法从使用 requests.post 得到的响应中解析任何 JSON 并得到以下错误:

“json.decoder.JSONDecodeError:预期值:第 4 行第 1 列(字符 3)”

我总是可以尝试解析完整的 HTML,但它又长又复杂,我宁愿使用友好的 JSON 信息。任何帮助将非常感激!

标签: pythonjsonhttppython-requestsscreen-scraping

解决方案


这可能是因为页面发送到浏览器的 javascript 正在向 API 发出请求以获取有关电影的 json 信息。

您可以尝试将请求直接发送到他们的 API(参见编辑 2),使用Beautiful Soup之类的库解析 html,或者您可以在 python 中使用专用的抓取库。我对scrapy有很好的体验。它比请求快得多

编辑:

如果页面使用动态加载的内容,我认为是这种情况,你必须在 PhantomJS 浏览器中使用selenium而不是请求。这是一个例子:

from bs4 import BeautifulSoup
from selenium import webdriver

url = "your url"
browser = webdriver.PhantomJS()
browser.get(url)
html = browser.page_source
soup = BeautifulSoup(html, 'lxml')

# Then parse the html code here

或者您可以使用 scrapy 加载动态内容

如果您想进行抓取,我推荐后者。学习需要更多时间,但这是一个更好的解决方案。

编辑2:

要直接向他们的 api 发出请求,您只需重现您看到的请求。使用谷歌浏览器,如果单击它并转到“标题”,您可以看到请求:

获取请求信息

之后,您只需使用 requests 库重现请求:

import requests
import json

url = 'http://paste.the.url/?here='

response = requests.get(url)

content = response.content

# in my case content was byte string 
# (it looks like b'data' instead of 'data' when you print it)
# if this is you case, convert it to string, like so

content_string = content.decode()

content_json = json.loads(content_string)

# do whatever you like with the data

您可以根据需要修改 url,例如,如果http://api.movies.com/?page=1&movietype=3您可以修改movietype=3movietype=2查看不同类型的电影等


推荐阅读