2014-09-27 66 views
1

我试图使用Python从此页面中查看信息:https://j2c-com.com/Euronaval14/catalogueWeb/catalogue.php?lang=gb。我特别感兴趣的是您点击个别参展商名称时出现的弹出窗口。具有挑战性的部分是它使用了很多JavaScript来使AJAX调用来加载数据。从AJAX onclick上刮掉内容弹出

我检查一下参展商在网络电话,看来,AJAX调用进入到这个网址(第一个参展商列表中,“AIAD和MOD ITALY”):https://j2c-com.com/Euronaval14/catalogueWeb/ajaxSociete.php?cle=D000365D000365&rnd=0.005115277832373977

我了解cle参数来自哪里(id<span>标记),但是,我没有得到的是rnd参数派生的位置。它只是一个随机数字吗?我试着为每个请求提供一个随机数字,但返回的HTML缺少弹出窗口的实际内容。

这使我相信,rnd属性不是一个随机数,或者我需要某种类型的cookie以便实际数据通过请求。

这里是我到目前为止的代码,我使用的请求和BeautifulSoup解析HTML:

import random 
import decimal 
import requests 
from bs4 import BeautifulSoup 

#base_url = 'https://j2c-com.com/Euronaval14/catalogueWeb/catalogue.php?lang=gb' 
base_url = 'https://j2c-com.com/Euronaval14/catalogueWeb/cataloguerecherche.php?listeFavoris=&typeRecherche=1&typeRechSociete=&typeSociete=&typeMarque=&typeDescriptif=&typeActivite=&choixSociete=&choixPays=&choixActivite=&choixAgent=&choixPavillon=&choixZoneExpo=&langue=gb&rnd=0.1410133063327521' 


def generate_random_number(i,d): 
    "Produce a random between 0 and 1, with 16 decimal digits" 
    return str(decimal.Decimal('%d.%d' % (random.randint(0,i),random.randint(0,d)))) 



r = requests.get(base_url) 
soup = BeautifulSoup(r.text) 

table = soup.find('table', {'id':'tableResultat'}) 

trs = table.findAll('tr') 


for tr in trs: 
    span = tr.find('span') 
    cle = span.get('id') 

    url = 'https://j2c-com.com/Euronaval14/catalogueWeb/ajaxSociete.php?cle=' + cle + '&rnd=' + generate_random_number(0,9999999999999999) 
    pop = requests.post(url) 

    print url 
    print pop.text 

    break 

你能帮助我明白,我怎么能成功占领弹出数据,或者是我米做错了吗?提前致谢!

回答

2

这不是关于rnd参数。它完全是随机的,并由Math.random() js函数填充。

正如您所怀疑的,它是关于cookies。随着每一个请求,cookie都是非常重要的。刚开始requests.Session(),并用它为每个请求你做:

Session对象允许您跨 坚持要求某些参数。它也会在所有来自 会话实例的请求中保持cookie。

... 

# start session 
session = requests.Session() 

r = session.get(base_url) 
soup = BeautifulSoup(r.text) 

table = soup.find('table', {'id':'tableResultat'}) 
trs = table.findAll('tr') 

for tr in trs: 
    span = tr.find('span') 
    cle = span.get('id') 

    url = 'https://j2c-com.com/Euronaval14/catalogueWeb/ajaxSociete.php?cle=' + cle + '&rnd=' + generate_random_number(0,9999999999999999) 
    pop = session.post(url) # <-- the POST request here contains cookies returned by the first GET call 

    print url 
    print pop.text 

    break 

它打印(参见HTML与所需要的数据填充):

https://j2c-com.com/Euronaval14/catalogueWeb/ajaxSociete.php?cle=D000365D000365&rnd=0.1625497943120751 
<table class='divAdresse'> 
    <tr> 
     <td class='ficheAdresse' valign='top'>Via Nazionale 54<br>IT-00184 - Roma<br><img 
       src='../../intranetJ2C/images/flags/IT.gif' style='margin-right:5px;'>ITALY<br><br>Phone: +39 06 488 
      0247 | Fax: +39 06 482 74 76<br><br>Website: <a href='http://www.aiad.it' target='_new'>www.aiad.it</a></td> 
    </tr> 
</table> 
<br> 
<b class="divMarque">Contact:</b><br> 
<font class="ficheAdresse"> Carlo Festucci - Secretary General<br> 
<a href="mailto:[email protected]">[email protected]</a></font> 
<br><br> 
<div id='divTexte' class='ficheTexte'></div> 

UPD。

您无法获得表格中其他参展商的结果的原因很难解释,但这里的要点是模拟所有随后在浏览器中单击行中引发的随后发出的ajax请求:

import random 
import decimal 
import requests 
from bs4 import BeautifulSoup 

base_url = 'https://j2c-com.com/Euronaval14/catalogueWeb/cataloguerecherche.php?listeFavoris=&typeRecherche=1&typeRechSociete=&typeSociete=&typeMarque=&typeDescriptif=&typeActivite=&choixSociete=&choixPays=&choixActivite=&choixAgent=&choixPavillon=&choixZoneExpo=&langue=gb&rnd=0.1410133063327521' 
fiche_url = 'https://j2c-com.com/Euronaval14/catalogueWeb/fiche.php' 
reload_url = 'https://j2c-com.com/Euronaval14/catalogueWeb/reload.php' 
data_url = 'https://j2c-com.com/Euronaval14/catalogueWeb/ajaxSociete.php' 


def generate_random_number(i,d): 
    "Produce a random between 0 and 1, with 16 decimal digits" 
    return str(decimal.Decimal('%d.%d' % (random.randint(0, i),random.randint(0, d)))) 


# start session 
session = requests.Session() 

r = session.get(base_url) 
soup = BeautifulSoup(r.content) 
for span in soup.select('table#tableResultat tr span'): 
    cle = span.get('id') 

    session.post(reload_url) 
    session.post(fiche_url, data={'page': 'page:catalogue', 
            'pasFavori': '1', 
            'listeFavoris': '', 
            'cle': cle, 
            'stand': '', 
            'rnd': generate_random_number(0, 9999999999999999)}) 
    session.post(reload_url) 
    pop = session.post(data_url, data={'cle': cle, 
             'rnd': generate_random_number(0, 9999999999999999)}) 

    print pop.text 

打印:

<table class='divAdresse'><tr><td class='ficheAdresse' valign='top'>Via Nazionale 54<br>IT-00184 - Roma<br><img src='../../intranetJ2C/images/flags/IT.gif' style='margin-right:5px;'>ITALY<br><br>Phone: +39 06 488 0247 | Fax: +39 06 482 74 76<br><br>Website: <a href='http://www.aiad.it' target='_new'>www.aiad.it</a></td></tr></table><br><b class="divMarque">Contact:</b><br><font class="ficheAdresse"> Carlo Festucci - Secretary General<br><a href="mailto:[email protected]">[email protected]</a></font><br><br><div id='divTexte' class='ficheTexte'></div> 
<table class='divAdresse'><tr><td class='ficheAdresse' valign='top'>An der Faehre 2<br>27809 - Lemwerder<br><img src='../../intranetJ2C/images/flags/DE.gif' style='margin-right:5px;'>GERMANY<br><br>Phone: +49 421 673 30 | Fax: +49 421 673 3115<br><br>Website: <a href='http://www.abeking.com' target='_new'>www.abeking.com</a></td></tr></table><br><b class="divMarque">Contact:</b><br><font class="ficheAdresse"> Thomas Haake - Sales Director Navy</font><br><br><div id='divTexte' class='ficheTexte'></div> 
<table class='divAdresse'><tr><td class='ficheAdresse' valign='top'>Mohamed Bin Khalifa Street (street 15)<br>PO Box 107241<br>107241 - Abu Dhabi<br><img src='../../intranetJ2C/images/flags/AE.gif' style='margin-right:5px;'>UNITED ARAB EMIRATES<br><br>Phone: +971 2 445 5551 | Fax: +971 2 445 0644</td></tr></table><br><b class="divMarque">Contact:</b><br><font class="ficheAdresse"> Pierre Baz - Business Development<br><a href="mailto:[email protected]">[email protected]</a></font><br><br><div id='divTexte' class='ficheTexte'></div> 
... 
+0

感谢您的帮助! – Abundnce10 2014-09-27 21:45:25

+0

看起来我很快就说话了。我尝试过使用requests.session(),但是当我浏览URL参数中的每个唯一cle值时,它只发回第一个参展商的数据(上面的HTML)。如果你从上面的代码中删除'break',当你在'trs:'循环中进行转换时,你会得到一个不同的结果吗? – Abundnce10 2014-09-30 03:20:43

+0

@ Abundnce10不接受答案有点不对,因为答案有助于解决您遇到的最初问题。无论如何,这是一个有趣的挑战 - 请参阅答案的UPD部分。谢谢。 – alecxe 2014-09-30 03:36:15