无法找到用于网页抓取的网站API-未找到json响应

时间:2020-07-16 10:23:30

标签: json web-scraping

我正在尝试从此网站上抓取市议会税阶数据,但找不到API:

https://ecitizen.aberdeencity.gov.uk/publicaccesslive/selfservice/services/counciltax/bandsearchresults.htm?action=pageNavigation&p=0

我已经阅读了有关Stack Overflow的先前答案以及包括以下内容的文章:

http://www.gregreda.com/2015/02/15/web-scraping-finding-the-api/

https://medium.com/@williamyeny/finding-ratemyprofessors-private-api-with-chrome-developer-tools-bd6747dd228d

我进入了“网络”标签-XHR /全部-标头/预览/响应,我唯一能找到的就是:

/**/jQuery11130005376436794664263_1594893863666({ "html" : "<li class='navbar-text myprofile_salutation'>Welcome Guest!</li><li role='presentation' class=''><a href='https://ecitizen.aberdeencity.gov.uk/publicaccesslive/selfservice/citizenportal/login.htm?redirect_url=https://ecitizen.aberdeencity.gov.uk/publicaccesslive/selfservice/dashboard.htm'> Sign In / Register <span class='icon-arrow-right17 pull-right visible-xs-block'></span></a></li>" });

作为测试,我使用了 AB24 4DE 进行搜索,但无法在json响应中的任何位置找到它。

据我所知,数据没有隐藏在Web套接字后面。

为此我运行了一个get请求并得到:

JSONDecodeError: Expecting value: line 10 column 1 (char 19)

我想念什么?

1 个答案:

答案 0 :(得分:1)

您正在正确地看待网络工具。我发现最好放大“网络”标签中提供的概述。您可以在浏览器中选择任意比例的动作。查看发生了什么请求。因此,当您单击搜索时,您可以专注于请求和响应的开始。它向您发出了两个请求,一个请求将信息发布到服务器,一个请求将信息获取到单独的url。

建议

我的建议是看一下网站,大概是使用硒,这是一个模仿浏览器活动的软件包。在下面,您将看到我对请求的研究。本质上,每次您进行搜索时,表单都会生成一个唯一的令牌。您必须复制才能获得正确的响应。事先很难知道。

也就是说,您可以使用硒模仿浏览器的活动,并自动输入邮政编码并自动单击搜索按钮。然后,您可以获取页面源HTML,并使用beautifulsoup对其进行解析。这是一个最小的可复制示例,向您展示了这一点。

编码示例

from selenium import webdriver 
from bs4 import BeautifulSoup 
driver = webdriver.Chrome(executable_path=r'c:\users\aaron\chromedriver.exe')
url = 'https://ecitizen.aberdeencity.gov.uk/publicaccesslive/selfservice/services/counciltax/bandsearch.htm'                          
driver.get(url)
driver.find_element_by_id('postcode').send_keys('AB24 4DE')
driver.find_element_by_xpath('//input[@class="btn btn-primary cap-submit-inline"]').click()
soup = BeautifulSoup(driver.page_source,'html.parser')

还有使浏览器变得无头的作用域,因此它不会弹出并且您将获得的只是解析的html。

代码说明

我们正在从Selenium导入webdriver,这提供了加载浏览器所需的模块。然后,我们创建该webdriver的实例,在这种情况下,我使用的是chrome,但您可以使用firefox或其他浏览器。

您需要从此处https://chromedriver.chromium.org/下载chromedriver。 Webdriver使用它来打开浏览器。

我们使用get webdriver get方法使chromedriver转到所需的特定页面。

Webdriver列出了find元素,您可以使用...。这里最简单的是find_element_by_id。我们可以在HTML中找到用于输入邮政编码的输入框的ID,这是我在这里完成的。 Send_keys将发送我们想要的任何文本,在这种情况下为AB24 4DE。

find_element_by_xpath使用XPATH选择器。 '//'遍历所有DOM,我们选择输入,然后[@ class =“”]部分选择特定的输入标记类。我们需要提交按钮。 click()方法将单击该浏览器。

点击完成后,我们便获取页面源代码,这是必要的,因为我们随后将其输入到BeuatifulSoup中,这将为我们提供所需的邮政编码的解析HTML。

反向工程HTTP请求

以下内容实际上是用于教育的,除非有人可以在向服务器发送请求之前获得唯一令牌。这是该网站根据搜索表单的工作方式。

从本质上看,它正在向服务器发送cookie,标题,参数和数据。 Cookies的会话ID在我的测试中似乎没有变化。 data变量是您可以更改邮政编码的位置,而且重要的是,每次要进行搜索时,ABCtoken都会更改,并且参数是对服务器的检查,以确保它不是机器人。

作为此处HTTP POST请求的示例。我们发送这个

cookies = {
    'JSESSIONID': '1DBAC40138879EB418C14AD83C05AD86',
}

headers = {
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'Origin': 'https://ecitizen.aberdeencity.gov.uk',
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-User': '?1',
    'Sec-Fetch-Dest': 'document',
    'Referer': 'https://ecitizen.aberdeencity.gov.uk/publicaccesslive/selfservice/services/counciltax/bandsearch.htm',
    'Accept-Language': 'en-US,en;q=0.9',
}

params = (
            ('action', 'validateData'),
         )

data = {
  'postcode': 'AB24 2RX',
  'address': '',
  'startSearch': 'Search',
  'ABCToken': '35fbfd26-cb4b-4688-ac01-1e35bcb8f63d'
}

收件人

https://ecitizen.aberdeencity.gov.uk/publicaccesslive/selfservice/services/counciltax/bandsearch.htm

然后,它使用相同的JSESSIONID和唯一的ABCtoken在此处执行HTTP GET请求,以获取您要bandsearchresults.html的数据

'https://ecitizen.aberdeencity.gov.uk/publicaccesslive/selfservice/services/counciltax/bandsearchresults.htm'

因此,它正在创建一个JSESSIONID,它与我测试中的任何邮政编码似乎都相同。那么当您使用相同的JSESSIONID并使用ABCtoken时,它会提供searchresults URL,您将获得正确的数据。