Очистка данных с сайта, URL которого не изменяется, при нажатии «Показать больше» - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь очистить все ссылки на статьи с сайта, и мне это удалось.

На странице сайта есть кнопка 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 голосов
/ 04 января 2019

Вот имитация запроса POST с использованием информации API, как я вижу на вкладке сети.Я вернулся к заголовкам, которые кажутся необходимыми.

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())
0 голосов
/ 07 января 2019

Чтобы очистить все ссылки на статьи, т.е. атрибуты href из URL , щелкнув ссылку с текстом как ПОКАЗАТЬ БОЛЬШЕ , вы можете использовать следующее решение:

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()
0 голосов
/ 03 января 2019

Похоже, ваш целевой ресурс дает нам хороший API для их статей.

Будет гораздо проще использовать его вместо селена.

Вы можете открыть эту страницу в Chrome. Затем откройте Dev Tools -> Network. Нажмите «Показать больше», и вы увидите запрос API с именем v2 (похоже, это шлюз GraphQL).

Что-то вроде

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

Вы можете имитировать этот запрос, но запрашивать столько «первых» статей, сколько хотите.

EDIT

Вы можете щелкнуть правой кнопкой мыши в DevTools и выбрать «копировать как cURL». Затем вставьте его в свой терминал. Итак, вы можете увидеть, как это работает.

После этого вы можете использовать библиотеку наподобие запросов , чтобы сделать это из вашего кода.

...