如何刮取按钮锁定的数据?

时间:2016-07-04 18:41:42

标签: jquery python html web-scraping beautifulsoup

我试图从网站上获取一些信息,但没有成功。

问题是只有在点击某个按钮后才会显示数据。

first_page

我想要的信息位于此标记中:

<div id="frmContact" class="contactForm hidden"></div>
<div class="btn btn-secondary viewnumber phone-trigger" data-ga-action="header">
    <a href="#" rel="nofollow">Ver telefone</a>
    <i class="icon"></i>
</div>

这可能与此行有关:

<form action="/noindex/doctor-phone" id="frmPhone" method="post"><input name="__RequestVerificationToken" type="hidden" value="3uFb11EKzbTh4TWoqXk025U7jS7QoV5-od7lSgSBzdu616u82jQAHiOTl2aB3q47aRCIg2CjVCjE6R6bUAqDplAOfeM1" /><input id="entityKey" name="entityKey" type="hidden" value="12898671" /><input id="placeType" name="placeType" type="hidden" value="" /><input id="placeKey" name="placeKey" type="hidden" value="" /></form>    <div id="phonePlacer"></div>

但我不知道如何正确使用此__RequestVerificationToken

我是否必须使用此信息向服务器发送request以获取电话信息?如果是这样,怎么做?

点击按钮后,会出现弹出窗口(我对info1到info4感兴趣):

enter image description here

我的代码:

page = BeautifulSoup(urllib2.urlopen('http://www.doctoralia.com.br/medico/RANDOM_PROFILE'), "html.parser")
hidden_tags = page.find_all("input", type="hidden")

for tag in hidden_tags:
    print tag

输出:

<input name="__RequestVerificationToken" type="hidden" value="gPYstKvmi4xBQsV81ECf5mYe695igvq8E2QqtOgBPqtRybEP74OEbSAe8uDg8dlZCpqib94FIrUoPMnpLTC0tY7kiJE1"/>
<input id="entityKey" name="entityKey" type="hidden" value="14336768"/>
<input id="placeType" name="placeType" type="hidden" value=""/>
<input id="placeKey" name="placeKey" type="hidden" value=""/>

2 个答案:

答案 0 :(得分:2)

正如您在“网络”标签中使用Google Chrome的开发工具时所看到的,它会向http://www.doctoralia.com.br/noindex/doctor-phone发送一个POST请求。此POST请求受CSRF保护,因此要伪造此请求以获取数据非常困难。

由于BeautifulSoup是HTML 解析器。您无法真正与网页进行互动。如果你真的想获得数据。您应该使用selenium之类的工具来模拟真实的浏览器。

请记住,数据不受保护只是为了绕过。他们可能不希望数据被删除,这样做可能是违法的。

答案 1 :(得分:1)

使用requests.Session对象非常简单,您只需要从初始页面和几个表单数据中提取__RequestVerificationToken标记。我使用完整列表的页面来获取数字和医生页面的链接,无论您决定从哪里获得数字,都适用相同的逻辑:

from bs4 import BeautifulSoup
import requests
from urlparse import urljoin

head = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
    "X-Requested-With": "XMLHttpRequest"}

base = "http://www.doctoralia.com.br/"

with requests.Session() as s:
    r = s.get('http://www.doctoralia.com.br/medicos/especialidade/dermatologistas-1314')
    page = BeautifulSoup(r.content, "html.parser")
    token = page.select_one("input[name=__RequestVerificationToken]"["value"])
    hidden_tags = page.select("article.media.doctor")
    for tag in hidden_tags:
        h3 = tag.select_one("h3")
        key = h3.a["data-track-click"]
        place = tag.select_one("span[data-location]")["data-location"].split("|", 1)[0]

       data = {"__RequestVerificationToken": token,
            "entityKey": key,
            "placeKey": place}
        resp = s.post("http://www.doctoralia.com.br/noindex/doctor-phone", data=data, headers=head)
        soup = BeautifulSoup(resp.content,"html.parser")
        print(urljoin(base,h3.a["href"]))
        print(soup.select_one("li.phone").text.strip())

它会为您提供每位医生的所有链接和电话号码,当您单击按钮时,您在弹出窗口中看到的任何内容都可以解析。基本表单数据是__RequestVerificationTokenentityKeyplaceKey似乎不会影响帖子,但不包括它。在这种情况下,标题也不是必需的,但再次添加用户代理并不是一个好主意。您可能希望在请求之间添加休眠,这样如果您提出大量请求,就不会对服务器进行锤击。还看着robots.txt:

User-agent: *
Disallow: /noindex/
Disallow: /usuarios/
Disallow: /users/
Disallow: /utilisateurs/
Disallow: /utenti/
Disallow: /gebruikers/
Disallow: /nutzer/
Disallow: /medical-center/m/
Disallow: /consultant/m/
Disallow: /centro-medico/m/
Disallow: /medico/m/
Disallow: /centre-medical/m/
Disallow: /medicin/m/
Disallow: /centro-medico/m/
Disallow: /medico/m/
Disallow: /centri-medici/m/
Disallow: /medecin/m/
Disallow: /healthpro/m/
Disallow: /facharzt/m/
Disallow: /sanit�tszentrum/m/
Disallow: /clickfav/
Disallow: /clicktlf/
Disallow: /reservas/
Disallow: /citas/
Disallow: /medisch-centrum/m/
Disallow: /deskundige/m/
Disallow: /arzt/m/
Disallow: /klinik/m/
Disallow: /citas/
Disallow: /turnos/
Disallow: /appuntamenti/
Disallow: /appointments/
Disallow: /consultas/
Disallow: /ws/Schedules.asmx/
Disallow: /RESOURCE NOT FOUND/
Disallow: /RESOURCE+NOT+FOUND/
Disallow: /RESOURCE%20NOT%20FOUND/
Disallow: /entities/

没有用户代理限制,您正在抓取的内容不被禁止