Разбор содержимого вопроса leetcode с запросами и BeautifulSoup - PullRequest
3 голосов
/ 15 июня 2019

Я пытаюсь разобрать содержание вопросов интервью по Leetcode.

Например, по https://leetcode.com/problems/two-sum/,

Я пытаюсь получить

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Это не казалось таким сложным.Я использовал запросы и BeautifulSoup, чтобы сделать это:

    url = 'https://leetcode.com/graphql/two-sum'
    try:
        page = requests.get(url)
    except (requests.exceptions.ReadTimeout,requests.exceptions.ConnectTimeout):
        print('time out')
        return 'time out'

    soup = BeautifulSoup(page.content, 'html.parser')
    print(soup.prettify())

Однако, как вы можете видеть в ответе страницы на странице через консоль разработчика (F12), ответ не включает содержимое, показанное настр.

Есть ли способ получить этот контент?

Ответы [ 3 ]

2 голосов
/ 15 июня 2019

Вам не нужен селен.Страница выполняет запрос POST для динамического содержимого.По сути, отправляет запрос MySql в базу данных бэкэнда.Итак, гораздо быстрее сделать следующее:

import requests
from bs4 import BeautifulSoup as bs

data = {"operationName":"questionData","variables":{"titleSlug":"two-sum"},"query":"query questionData($titleSlug: String!) {\n  question(titleSlug: $titleSlug) {\n    questionId\n    questionFrontendId\n    boundTopicId\n    title\n    titleSlug\n    content\n    translatedTitle\n    translatedContent\n    isPaidOnly\n    difficulty\n    likes\n    dislikes\n    isLiked\n    similarQuestions\n    contributors {\n      username\n      profileUrl\n      avatarUrl\n      __typename\n    }\n    langToValidPlayground\n    topicTags {\n      name\n      slug\n      translatedName\n      __typename\n    }\n    companyTagStats\n    codeSnippets {\n      lang\n      langSlug\n      code\n      __typename\n    }\n    stats\n    hints\n    solution {\n      id\n      canSeeDetail\n      __typename\n    }\n    status\n    sampleTestCase\n    metaData\n    judgerAvailable\n    judgeType\n    mysqlSchemas\n    enableRunCode\n    enableTestMode\n    envInfo\n    libraryUrl\n    __typename\n  }\n}\n"}

r = requests.post('https://leetcode.com/graphql', json = data).json()
soup = bs(r['data']['question']['content'], 'lxml')
title = r['data']['question']['title']
question =  soup.get_text().replace('\n',' ')
print(title, '\n', question)
1 голос
/ 15 июня 2019

Вам нужно загрузить java-скрипты на странице, а затем получить содержимое страницы. Самый простой способ сделать это - использовать Selenium.

from selenium import webdriver
from time import sleep
import os


# initialise browser
browser = webdriver.Chrome(os.getcwd() + '/chromedriver')
# load page
browser.get('https://leetcode.com/problems/two-sum/')

# execute java script
browser.execute_script("return document.getElementsByTagName('html')[0].innerHTML")

# wait page to load
sleep(5)

# get selected content
problem_description = browser.find_element_by_class_name('question-content__JfgR')
print(problem_description.text)

Выход:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
0 голосов
/ 15 июня 2019

Сайт создается путем выполнения динамического Javascript.Так что вы не получите его, просто используя requests.Вы можете использовать селен для имитации браузера Firefox.

Проверьте учебник .

...