scrapy 零碎 AJAX 发送请求以获取生成的HTML的响应

uqxowvwt  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(131)

我想从像this这样的网站抓取数据。
要手动显示所有报价,必须点击页面底部的“显示更多结果”按钮,直到所有报价都显示出来。点击它后,一个 AJAX 请求被发送到服务器,服务器响应此事件显示更多HTML(我想刮取)。
请求副本URL如下所示:

https://www.cardmarket.com/en/Magic/AjaxAction

但我不想保留起始URL,而是加载更多内容。响应也不提供JSON或HTML,总是如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<ajaxResponse><rows>PGRpdiBpZ...</rows><newPage>1</newPage></ajaxResponse>

类似问题的其他答案通常会得到一个JSON作为响应或直接的HTML或推荐使用Beautiful Soup,但我也担心爬行速度。
如何加载缺少的HTML并以有效的方式获取数据?

gdx19jrr

gdx19jrr1#

下面的selenium, bs4 and pandas示例运行得很顺利,我必须使用Javascript执行来单击并完成show more result

范例:

import time
from bs4 import BeautifulSoup
import pandas as pd
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By

options = webdriver.ChromeOptions()
options.add_argument("start-maximized")

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()),options=options)

url = 'https://www.cardmarket.com/en/Magic/Products/Singles/Exodus/Survival-of-the-Fittest'
driver.get(url)
time.sleep(5)

lst=[]
while True:

    soup=BeautifulSoup(driver.page_source,'lxml')
    for card in soup.select('[class="d-flex has-content-centered mr-1"] > a'):
        lst.append({'name': card.text})

    try:     
        driver.execute_script("arguments[0].scrollIntoView();",driver.find_element(By.XPATH,'//*[@id="loadMore"]/button/span[2]'))
        pos= driver.find_element(By.XPATH,'//*[@id="loadMore"]/button/span[2]').click()

        time.sleep(2)
    except:
        break

df=pd.DataFrame(lst)
print(df)

输出:

name
0               Lugones
1              odaJoana
2        Arcana-Trieste
3        Arcana-Trieste
4              Impavido
..                  ...
145              yoeril
146  JacobMartinNielsen
147               Artia
148               Nanau
149           magictuga

[150 rows x 1 columns]

相关问题