我正在尝试在脚本中获取网站HTML,以便稍后进行抓取,但是在获取它时遇到了问题,我不确定为什么,但是我只在请求时才获得页面HTML的一部分它。
首先,我尝试在请求库中请求该请求,但该请求不起作用时,我尝试添加一些标头并将其与请求一起发送,但是我对cookie感到困惑,我是否需要发送它们以及我应该使用什么?请求会话或基本请求?
link访问网站
最终,我想出了这个功能,但并不能真正获得我想要的东西:
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
正如我所解释的,我得到的结果只是页面的一部分。
答案 0 :(得分:2)
在我看来,页面必须动态加载内容或其他内容。在其他我完成的项目中找到的解决方案是使用the selenium
module在浏览器对象中加载页面,然后以特定方式与页面交互后从页面获取源代码。您可能会遇到的一个示例看起来像这样:
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对页面所做的更改。知道要尝试单击的按钮后,您可以locate the elements,然后在程序中自动对它们执行诸如.click()
之类的操作。一旦您的脚本抓取了所需的所有数据,就可以在无头模式下运行selenium,它甚至不会在屏幕上弹出窗口!一切都会在幕后。
答案 1 :(得分:1)
数据似乎是动态加载的,在这种情况下,这对我们来说是个好消息。 在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。
答案 2 :(得分:0)
当进一步向下滚动时,页面的其余内容看起来是动态加载的。动态页面内容的加载通常由浏览器执行的javascript代码完成。
因此,仅使用请求库将不会获得所有页面内容。简单来说,您需要使用某种浏览器模拟功能。
您可以使用例如来实现“加载更多页面内容”功能。 Selenium driver for python。此外,您需要添加一个浏览器,在其中可以使用Selenium,而我使用的是PhantomJS,它是无头浏览器。
以下是简短说明:
1.下载适用于您的操作系统的Selenium驱动程序
2.下载Selenium客户端和WebDriver语言绑定here
3.导入虚拟显示
4.导入Selenium Webdriver
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_name
很重要,在我的例子中是“ divBorder3”。
我希望这有助于开始。您显然必须遍历每个已加载的内容部分。我建议使用Scrapy是一个Web爬网框架,它关心在页面上进行迭代等。如果与Selenium或Beautiful Soap结合使用,它确实非常强大。
答案 3 :(得分:0)
如果要查询内部JSON URL,请确保发送适当的引荐来源网址。
此外,在使用Selenium时,您可以在找到所需的内容后停止加载页面。不要忘记关闭浏览器。