使用beautifulsoup动态抓取加载页面

2024-10-02 20:40:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我是新来的漂亮组合。我正在尝试从https://indianrecipes.com/new_and_popular中获取所有的食物配方和链接以及配料 问题是这个网站只会在向下滚动时加载更多的食物。我提到过这个问题,但没能充分利用。 我检查了inspect元素中的network选项卡,发现每次向下滚动时,都会发送一个XHR请求

api?tm=1565542062069
api?tm=1565542065302
api?tm=1565542073116
api?tm=1565542075617

有没有可能在python中模拟这样的请求,从该页面提取所有的食物配方?在


Tags: andhttpscomapinew网站链接配方
3条回答

api?tm=1565542075617中的数字是以毫秒为单位的epoch时间戳。对于请求,这可能不是必需的。在

重要的是要查看服务器将响应请求发送到哪些数据。在XHR请求中,向下滚动到Request Payload以查看有效负载。在

下面是一个Python代码,它在初始的offset个配方之后加载recipes_per_page个配方。在

import requests

offset = 50
recipes_per_page = 50
data = [{'jsonrpc': '2.0', 'method': 'recipe.get_trending', 'id': 1, 'params': [offset, recipes_per_page, None, False]}]
response = requests.post('https://indianrecipes.com/api', json=data)

recipes = response.json()[0]['result']['recipes']

我制作了一个简单的脚本,在这个脚本中,您可以指定每页的食谱数量和您要刮取的页数。它以JSON格式返回数据:

from itertools import count, islice
import requests
import json

url = 'https://indianrecipes.com/api'
data = {"id":1,"jsonrpc":"2.0","method":"recipe.get_trending","params":[50,50,None,False]}

per_page = 50
num_pages = 2

for i, c in enumerate( islice(count(0, per_page), 0, num_pages), 1):
    print('Page no.{} :'.format(i))
    print('-' * 80)
    data['params'][0] = c
    data['params'][1] = per_page
    json_data = requests.post(url, json=data).json()
    print(json.dumps(json_data, indent=4))
    print('-' * 80)

印刷品:

^{pr2}$

你必须使用selenium将javascript从网页加载到html 然后使用selenium的滚动代码

import requests
from bs4 import BeautifulSoup
from selenium import webdriver
import pandas as pd
import time
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome('/home/sush/Downloads/Compressed/chromedriver_linux64/chromedriver')

driver.get('https://indianrecipes.com/new_and_popular')


heights = []
counter = 0
for i in range(1,300):
    bg = driver.find_element_by_css_selector('body')
    time.sleep(0.1)
    bg.send_keys(Keys.END)
    heights.append(driver.execute_script("return document.body.scrollHeight"))
    try :
        bottom = heights[i-16]
    except:
        pass
    if i%16 ==0:
        new_bottom = heights[i-1]
        if bottom == new_bottom:
            break

然后使用beauthousoup从

soup = BeautifulSoup(driver.page_source, 'lxml')

相关问题 更多 >