Python 为什么当我';我要它?
我试图在我的脚本中获取网站HTML,以便稍后可以将其刮取,但我在获取时遇到了问题,我不知道为什么,但我在请求时只获取了部分页面HTML 首先,我尝试用请求库请求它,但没有成功。我尝试添加一些标题并将其与请求一起发送,但我被cookies弄糊涂了,我需要发送它们吗?我应该使用什么?请求会话还是基本请求 系上领带 最终,我提出了这个函数,它并没有真正满足我的需求:Python 为什么当我';我要它?,python,python-requests,Python,Python Requests,我试图在我的脚本中获取网站HTML,以便稍后可以将其刮取,但我在获取时遇到了问题,我不知道为什么,但我在请求时只获取了部分页面HTML 首先,我尝试用请求库请求它,但没有成功。我尝试添加一些标题并将其与请求一起发送,但我被cookies弄糊涂了,我需要发送它们吗?我应该使用什么?请求会话还是基本请求 系上领带 最终,我提出了这个函数,它并没有真正满足我的需求: def get_page_html(): link = 'https://stips.co.il/explore' header
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
分析页面,找出加载额外内容的HTMLclass\u name
,这一点很重要,在我的例子中,它是“divBorder3”
我希望这有助于开始。显然,您必须循环每个加载的内容部分。我建议使用它是一个web爬行框架,它关注页面的迭代等。如果与Selenium或相结合,它确实非常强大。如果您要查询内部JSON URL,请确保您发送了正确的参考
此外,在使用Selenium时,您可以在找到所需内容后停止加载页面。别忘了关闭浏览器。Hi@Reedinationer,我已经在铃声中给出了答案。看起来底层API调用是通过网络流量进行的,它输出非常好的JSON数据。我很想听听你对我的解决方案的想法。我对Python很陌生。谢谢!我不知道这一点,这对我有帮助:)请不要破坏你的帖子,为别人做更多的工作。通过在Stack Exchange网络上发布,您已授予Stack Exchange在下不可撤销的权利,以分发该内容(即,无论您未来的选择如何)。根据堆栈交换策略,帖子的非破坏版本是分发的版本。因此,任何故意破坏行为都将恢复原状。如果您想了解有关删除帖子的更多信息,请参阅: