Python 为什么当我';我要它?

Python 为什么当我';我要它?,python,python-requests,Python,Python Requests,我试图在我的脚本中获取网站HTML,以便稍后可以将其刮取,但我在获取时遇到了问题,我不知道为什么,但我在请求时只获取了部分页面HTML 首先,我尝试用请求库请求它,但没有成功。我尝试添加一些标题并将其与请求一起发送,但我被cookies弄糊涂了,我需要发送它们吗?我应该使用什么?请求会话还是基本请求 系上领带 最终,我提出了这个函数,它并没有真正满足我的需求: def get_page_html(): link = 'https://stips.co.il/explore' header

我试图在我的脚本中获取网站HTML,以便稍后可以将其刮取,但我在获取时遇到了问题,我不知道为什么,但我在请求时只获取了部分页面HTML

首先,我尝试用请求库请求它,但没有成功。我尝试添加一些标题并将其与请求一起发送,但我被cookies弄糊涂了,我需要发送它们吗?我应该使用什么?请求会话还是基本请求

系上领带

最终,我提出了这个函数,它并没有真正满足我的需求:

def get_page_html():
    link = 'https://stips.co.il/explore'
headers={
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.9',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive',
    'Host': 'stips.co.il',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
}
responde = requests.post(link, headers=headers)
return responde.text

正如我所解释的,我得到的结果只是页面的一部分。

在我看来,页面必须动态加载内容或其他内容。我在其他项目中发现的解决方案是使用浏览器对象加载页面,然后在以特定方式与页面交互后从页面获取源代码。一个你可以随意处理的例子如下:

from selenium import webdriver
browser = webdriver.Chrome() # You'll need to download drivers from link above
browser.implicitly_wait(10) # probably unnecessary, just makes sure all pages you visit fully load
browser.get('https://stips.co.il/explore')
while True:
    input('Press Enter to print HTML')
    HTML = browser.page_source
    print(HTML)

这将让您看到HTML是如何随着您对页面所做的操作而变化的。一旦知道要单击哪些按钮,就可以在程序中自动单击这些按钮,然后执行类似于
。单击()
。一旦脚本抓取了所有需要的数据,就可以在无头模式下运行selenium,它甚至不会在屏幕上弹出窗口!这一切都将发生在幕后。

数据似乎是动态加载的,这(在本例中)对我们来说是个好消息。 在Chrome中按F12键并导航到网络选项卡将显示底层API调用

import requests

headers = {
    'Referer': 'https://stips.co.il/explore',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
    'Accept': 'application/json, text/plain, */*',
    'Origin': 'https://stips.co.il',

}

url = 'https://stips.co.il/api?name=objectlist&api_params={"method":"ask.new","safe_filter":true,"page":1}'

r = requests.get(url, headers=headers)
j = r.json()
上面的脚本输出高度结构化的JSON数据,正如您在
api_params
中看到的,您可以每次迭代并更新页码

祝你好运


提示-留意速率限制,可能在每次请求之间探索
time.sleep(x)
一段时间,也可能使用代理屏蔽IP

向下滚动时,页面内容的其余部分看起来是动态加载的。动态页面内容的加载通常由浏览器执行的javascript代码完成

因此,仅使用请求库无法获取所有页面内容。简单地说,您需要使用某种浏览器模拟功能

您可以通过使用,例如,实现“加载更多页面内容”功能。此外,您需要添加一个浏览器,您可以在其中使用Selenium,我使用了PhantomJS,它是一个无头浏览器

这里有一个简短的说明: 1.为您的操作系统下载Selenium驱动程序 2.下载Selenium客户端和WebDriver语言绑定 3.导入虚拟显示 4.导入Selenium Web驱动程序 5.实现
scrollDown()
功能

from pyvirtualdisplay import Display
from selenium import webdriver

with Display():
    driver = webdriver.PhantomJS()

# page scrolling functionality with selenium
def scrollDown(browser, class_name, sec, response_url):
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    browser.get(response_url)
    element0 = WebDriverWait(browser, 30).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, class_name)))
    prev_part = len(element0)
    browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(sec)
    element1 = WebDriverWait(browser, 30).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, class_name)))
    curr_part = len(element1)
    while curr_part > prev_part:  # breaking condition for scrolling
        browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(sec)
        element1 = WebDriverWait(browser, 30).until(
            EC.presence_of_all_elements_located((By.CLASS_NAME, class_name)))
        prev_part = curr_part
        curr_part = len(element1)
    return browser
使用
scrollDown()
函数,如下所示:

driver.get(responde)
# scroll page with selenium
driver = scrollDown(driver, "divBorder3", 20, responde)
response = driver.page_source
分析页面,找出加载额外内容的HTML
class\u name
,这一点很重要,在我的例子中,它是“divBorder3”


我希望这有助于开始。显然,您必须循环每个加载的内容部分。我建议使用它是一个web爬行框架,它关注页面的迭代等。如果与Selenium或相结合,它确实非常强大。

如果您要查询内部JSON URL,请确保您发送了正确的参考


此外,在使用Selenium时,您可以在找到所需内容后停止加载页面。别忘了关闭浏览器。

Hi@Reedinationer,我已经在铃声中给出了答案。看起来底层API调用是通过网络流量进行的,它输出非常好的JSON数据。我很想听听你对我的解决方案的想法。我对Python很陌生。谢谢!我不知道这一点,这对我有帮助:)请不要破坏你的帖子,为别人做更多的工作。通过在Stack Exchange网络上发布,您已授予Stack Exchange在下不可撤销的权利,以分发该内容(即,无论您未来的选择如何)。根据堆栈交换策略,帖子的非破坏版本是分发的版本。因此,任何故意破坏行为都将恢复原状。如果您想了解有关删除帖子的更多信息,请参阅: