从点击“显示更多”后URL不变的站点中收集数据

时间:2019-01-03 15:15:25

标签: python selenium web-scraping lazy-loading webdriverwait

我正在尝试从网站上抓取所有文章链接,而我是否成功做到了。

站点页面上有一个Show more按钮,用于加载更多文章。

我正在使用Selenium单击此按钮,该按钮也有效。

问题在于单击Show more不会更改页面的URL,因此,我只能抓取默认显示的初始链接。

这是代码片段:

def startWebDriver():
    global driver
    options = Options()
    options.add_argument("--disable-extensions")
    driver = webdriver.Chrome(executable_path = '/home/Downloads/chromedriver_linux64/chromedriver',options=options)

startWebDriver()
count = 0 
s = set()

driver.get('https://www.nytimes.com/search? endDate=20181231&query=trump&sort=best&startDate=20180101')
time.sleep(4)
element = driver.find_element_by_xpath('//*[@id="site-content"]/div/div/div[2]/div[2]/div/button')

while(count < 10):
    element.click()
    time.sleep(4)
    count=count+1

url = driver.current_url

我希望在单击Show More 10次后将所有文章链接显示在页面上

3 个答案:

答案 0 :(得分:0)

似乎您的目标资源为我们的文章提供了一个不错的API。

使用它代替硒会容易得多。

您可以在Chrome中打开该页面。然后打开开发工具->网络。单击“显示更多”,您可以看到名为v2的API请求(看起来像是GraphQL网关)。

类似

{
    "operationName":"SearchRootQuery",
    "variables":{
        "first":10,
        "sort":"best",
        "beginDate":"20180101",
        "endDate":"20181231",
        "text":"trump" ...
}}

您可以模仿该请求,但可以根据需要询问尽可能多的“第一”文章。

编辑

您可以右键单击DevTools并选择“复制为cURL”。然后将其粘贴到您的终端。这样您就可以了解其工作原理。

之后,您可以使用requests之类的库通过代码进行操作。

答案 1 :(得分:0)

这是使用API​​信息的POST请求的模拟,正如我在“网络”标签中看到的那样。我已经剥离了似乎是必需的标题。

import requests
url = 'https://samizdat-graphql.nytimes.com/graphql/v2'
headers = {
         'nyt-app-type': 'project-vi',
         'nyt-app-version': '0.0.3',
         'nyt-token': 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlYOpRoYg5X01qAqNyBDM32EI/E77nkFzd2rrVjhdi/VAZfBIrPayyYykIIN+d5GMImm3wg6CmTTkBo7ixmwd7Xv24QSDpjuX0gQ1eqxOEWZ0FHWZWkh4jfLcwqkgKmfHJuvOctEiE/Wic5Qrle323SMDKF8sAqClv8VKA8hyrXHbPDAlAaxq3EPOGjJqpHEdWNVg2S0pN62NSmSudT/ap/BqZf7FqsI2cUxv2mUKzmyy+rYwbhd8TRgj1kFprNOaldrluO4dXjubJIY4qEyJY5Dc/F03sGED4AiGBPVYtPh8zscG64yJJ9Njs1ReyUCSX4jYmxoZOnO+6GfXE0s2xQIDAQAB'
}

data = '''
{"operationName":"SearchRootQuery","variables":{"first":10,"sort":"best","beginDate":"20180101","text":"trump","cursor":"YXJyYXljb25uZWN0aW9uOjk="},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"d2895d5a5d686528b9b548f018d7d0c64351ad644fa838384d94c35c585db813"}}}
'''
with requests.Session() as r:
    re = r.post(url, headers = headers, data = data)
    print(re.json())

答案 2 :(得分:0)

要从URL中刮取所有文章链接,即Rinkebyhref属性,请单击以下文本链接,显示更多,您可以使用以下解决方案:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException

options = webdriver.ChromeOptions() 
options.add_argument("start-maximized")
options.add_argument('disable-infobars')
driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("https://www.nytimes.com/search?%20endDate=20181231&query=trump&sort=best&startDate=20180101")
myLength = len(WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//main[@id='site-content']//figure[@class='css-rninck toneNews']//following::a[1]"))))

while True:
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    try:
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Show More']"))).click()
        WebDriverWait(driver, 20).until(lambda driver: len(driver.find_elements_by_xpath("//main[@id='site-content']//figure[@class='css-rninck toneNews']//following::a[1]")) > myLength)
        titles = driver.find_elements_by_xpath("//main[@id='site-content']//figure[@class='css-rninck toneNews']//following::a[1]")
        myLength = len(titles)
    except TimeoutException:
        break

for title in titles:
    print(title.get_attribute("href"))
driver.quit()