Скрипт оболочки для загрузки большого количества HTML-файлов и их статического хранения со всеми CSS - PullRequest
0 голосов
/ 09 июня 2019

Я разместил на форуме наук много постов (примерно 290 вопросов), которые Я хотел бы получить, загрузив их со всеми соответствующими ответами.

Первая проблема заключается в том, что мне необходимо войти в личный кабинет, чтобы получить список всех сообщений . Как обойти этот первый барьер, чтобы иметь возможность с помощью сценария оболочки или одной команды wget вернуть все URL и их содержимое. Могу ли я передать wget логин и пароль для регистрации и перенаправления на соответствующий URL, содержащий список всех сообщений?

Как только эта первая проблема будет решена, вторая проблема заключается в том, что мне нужно начать с 6 разных страниц меню, которые содержат заголовок и ссылку на вопросы.

Более того, что касается некоторых моих вопросов, ответы и обсуждения могут быть на нескольких страницах.

Поэтому мне интересно, смогу ли я выполнить эту операцию глобальной загрузки, зная, что я хотел бы хранить их статически с локальным CSS, хранящимся также на моем компьютере (чтобы сохранить тот же формат в моем браузере, когда я обращаюсь к ним на моем ПК). 1017 *

URL-адрес первой страницы меню вопросов (после того, как я вошел на веб-сайт: это также может быть проблемой для загрузки с wget, если я обязан быть подключенным).

Пример URL-адреса, содержащего список сообщений после входа в систему:

https://forums.futura-sciences.com/search.php?searchid=22897684

остальные страницы (там все 6 или 7 страниц заголовков обсуждений в общей сложности появляются на странице главного меню) имеют формат: "https://forums.futura -sciences.com / search.php? Searchid = 22897684 & р = & страница = 2 " (для страницы 2)

https://forums.futura -sciences.com / search.php? Searchid = 22897684 & р = & страница = 5 (для страницы 5)

На каждой из этих страниц можно увидеть заголовок и ссылку на каждое из обсуждений, которое я хотел бы также загрузить с помощью CSS (зная, что каждое обсуждение также может содержать несколько страниц):

например, первая страница обсуждения "https://forums.futura -sciences.com / archives / 804364-демонстрация-дилатация-temps.html "

имеет страницу 2: "https://forums.futura -sciences.com / archives / 804364-демонстрация-временная-температура-2.html "

и стр. 3: "https://forums.futura -sciences.com / archives / 804364-демонстрация-временная температура-3.html "

Наивно я пытался сделать все это только одной командой: (с примером URL в моем личном пространстве, который я взял в начале поста, то есть "https://forums.futura -sciences.com/search.php?searchid=22897684 "):

wget -r --no-check-certificate --html-extension --convert-links "https://forums.futura-sciences.com/search.php?searchid=22897684"

но, к сожалению, эта команда загружает все файлы, и даже, может быть, не то, что я хочу, т.е. мои обсуждения.

Я не знаю, какой подход использовать: я должен сначала сохранить все URL в файле (со всеми подстраницами, содержащими все ответы и глобальное обсуждение каждого исходного вопроса)?

и после, я мог бы сделать wget -i all_URL_questions.txt

Кто-нибудь может мне помочь с выполнением этой операции?

ОБНОВЛЕНИЕ 1: моей проблеме нужен скрипт, я пробовал с python следующие вещи:

1)

import urllib, urllib2, cookielib

username = 'USERNAME'
password = 'PASSWORD'

cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
login_data = urllib.urlencode({'username' : username, 'password' : password})
opener.open('https://forums.futura-sciences.com/login.php', login_data)
resp = opener.open('https://forums.futura-sciences.com/search.php?do=finduser&userid=253205&contenttype=vBForum_Post&showposts=1')
print resp.read()

Но напечатанная страница не является страницей моего дома в личном пространстве.

2)

import requests

# Fill in your details here to be posted to the login form.
payload = { 
    'inUserName': 'USERNAME',
    'inUserPass': 'PASSWORD'
}

# Use 'with' to ensure the session context is closed after use.
with requests.Session() as s:
    p = s.post('https://forums.futura-sciences.com/login.php?do=login', data=payload)
    # print the html returned or something more intelligent to see if it's a successful login page.
    print p.text.encode('utf8')

    # An authorised request.
    r = s.get('https://forums.futura-sciences.com/search.php?do=finduser&userid=253205&contenttype=vBForum_Post&showposts=1')
    print r.text.encode('utf8')

и здесь это не работает

3)

import requests
import bs4 

site_url = 'https://forums.futura-sciences.com/login.php?do=login'
userid = 'USERNAME'
password = 'PASSWWORD'

file_url = 'https://forums.futura-sciences.com/search.php?do=finduser&userid=253205&contenttype=vBForum_Post&showposts=1' 
o_file = 'abc.html'  

# create session
s = requests.Session()
# GET request. This will generate cookie for you
s.get(site_url)
# login to site.
s.post(site_url, data={'vb_login_username': userid, 'vb_login_password': password})
# Next thing will be to visit URL for file you would like to download.
r = s.get(file_url)

# Download file
with open(o_file, 'wb') as output:
    output.write(r.content)
print("requests:: File {o_file} downloaded successfully!")

# Close session once all work done
s.close()

То же самое, содержимое неверно

4)

from selenium import webdriver

# To prevent download dialog
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2) # custom location
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.download.dir', '/tmp')
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv')

webdriver.get('https://forums.futura-sciences.com/')
webdriver.find_element_by_id('ID').send_keys('USERNAME')
webdriver.find_element_by_id ('ID').send_keys('PASSWORD')
webdriver.find_element_by_id('submit').click()
browser = webdriver.Firefox()
browser.get('https://forums.futura-sciences.com/search.php?do=finduser&userid=253205&contenttype=vBForum_Post&showposts=1')

По-прежнему не удается войти в систему с USERNAME и PASSSWORD и получить содержимое домашней страницы личного пространства

5)

from selenium import webdriver
from selenium.webdriver.firefox.webdriver import FirefoxProfile
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import time

def MS_login(username, passwd):  # call this with username and password

firefox_capabilities = DesiredCapabilities.FIREFOX
    firefox_capabilities['moz:webdriverClick'] = False
    driver = webdriver.Firefox(capabilities=firefox_capabilities)
    fp = webdriver.FirefoxProfile()
    fp.set_preference("browser.download.folderList", 2) # 0 means to download to the desktop, 1 means to download to the default "Downloads" directory, 2 means to use the directory
    fp.set_preference("browser.download.dir","/Users/user/work_archives_futura/")
    driver.get('https://forums.futura-sciences.com/') # change the url to your website
    time.sleep(5) # wait for redirection and rendering
    driver.delete_all_cookies() # clean up the prior login sessions
    driver.find_element_by_xpath("//input[@name='vb_login_username']").send_keys(username)

elem  = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//input[@name='vb_login_password']")))
    elem.send_keys(Keys.TAB)

driver.find_element_by_xpath("//input[@type='submit']").click()

    print("success !!!!")

driver.close() # close the browser
    return driver

if __name__ == '__main__':
    MS_login("USERNAME","PASSWORD")

Окно хорошо открыто, имя пользователя заполнено, но невозможно заполнить или отправить пароль и нажать кнопку отправить.

Я начинаю разочаровываться.

ps: основная проблема может быть связана с тем, что поле пароля имеет свойство display:none, поэтому я не могу смоделировать операцию TAB в поле пароля и передать его, как только я введу имя для входа.

Любая помощь приветствуется

РЕДАКТИРОВАТЬ 1: Неужели нет никого, кто мог бы дать предложения?Я знаю, что это немного сложно, но должно быть решение, по крайней мере, я надеюсь ...

Ответы [ 2 ]

1 голос
/ 10 июля 2019

@ Исследователь прав в своих советах, когда дело доходит до библиотеки запросов.Вы не публикуете все параметры запроса, которые отправляет браузер.В целом, я думаю, что будет сложно получить запросы на получение всего, когда вы учитываете статический контент и клиентский javascript

В вашем коде селена из раздела 4 есть несколько ошибок:

 # yours
webdriver.find_element_by_id('ID').send_keys('USERNAME')
webdriver.find_element_by_id ('ID').send_keys('PASSWORD')
webdriver.find_element_by_id('submit').click()

# should be
webdriver.find_element_by_id('vb_login_username').send_keys('USERNAME')
webdriver.find_element_by_id('vb_login_password').send_keys('PASSWORD')
webdriver.find_element_by_xpath("//input[@type='submit']").click()

Возможно, вам придется поиграть с xpath для кнопки отправки.

Подсказка : вы можете отладить по пути, сделав снимки экрана:

webdriver.find_element_by_id('vb_login_username').send_keys('USERNAME')
webdriver.find_element_by_id('vb_login_password').send_keys('PASSWORD')

webdriver.get_screenshot_as_file('before_submit.png')
webdriver.find_element_by_xpath("//input[@type='submit']").click()
webdriver.get_screenshot_as_file('after_submit.png')

1 голос
/ 07 июля 2019

- Здравствуйте- youpilat13!

Кажется, вы уже достаточно хорошо осведомлены о том, как использовать различные методы. Не хватало только правильных имен полей в запросе на публикацию.

Я использовал инструменты разработчика Chrome (f12 - затем перейдите на вкладку «Сеть»). Если вы войдете в систему и быстро прекратите перенаправление окна браузера, вы сможете увидеть полный запрос к login.php, просмотреть поля и т. Д.

С этим я смог построить это для вас. Он включает в себя хорошую функцию сброса ответов. Для проверки работоспособности моего кода вы можете использовать свой реальный пароль для положительного регистра и строку с неверным паролем для отрицательного регистра.

import requests
import json

s = requests.Session()

def dumpResponseData(r, fileName):
    print(r.status_code)

    print(json.dumps(dict(r.headers), indent=1))

    cookieDict = s.cookies.get_dict()
    print(json.dumps(cookieDict, indent=1))

    outfile = open(fileName, mode="w")
    outfile.write(r.text)
    outfile.close()

username = "your-username"
password = "your-password"
# password = "bad password"

def step1():
    data = dict()
    data["do"] = "login"
    data["vb_login_md5password"] = ""
    data["vb_login_md5password_utf"] = ""
    data["s"] = ""
    data["securitytoken"] = "guest"
    data["url"] = "/search.php?do=finduser&userid=1077817&contenttype=vBForum_Post&showposts=1"
    data["vb_login_username"] = username
    data["vb_login_password"] = password

    p = s.post('https://forums.futura-sciences.com/login.php?do=login', data=data)

    # Logged In?
    if "vbseo_loggedin" in s.cookies.keys():
        print("Logged In!")
    else:
        print("Login Failed :(")

if __name__ == "__main__":
    step1()

У меня нет ни одной записи в моей недавно созданной учетной записи futura, поэтому я не могу больше тестировать вас - я не хочу спамить их форум мусором.

Но я бы, вероятно, начал с запроса URL-адреса поиска по почте и очистил ссылки с помощью bs4.

Тогда, возможно, вы могли бы просто использовать wget -r для каждой ссылки, которую вы удалили.

Дайте мне знать, если вам понадобится дополнительная помощь.

...