Ответ 1
Трюк здесь заключается в том, чтобы проверять запросы, которые входят и выходят из действия изменения страницы, когда вы нажимаете на ссылку, чтобы просмотреть другие страницы. Способ проверить это - использовать инструмент проверки Chrome (нажав F12) или установить расширение Firebug в Firefox. В этом ответе я буду использовать инструмент проверки Chrome. Ниже приведены мои настройки.
Теперь то, что мы хотим увидеть, - это либо запрос GET
на другую страницу, либо запрос POST
, который изменяет страницу. Пока инструмент открыт, щелкните номер страницы. В течение очень короткого момента появится только один запрос, который будет отображаться, и это метод POST
. Все остальные элементы будут быстро следовать и заполнять страницу. Смотрите ниже, что мы ищем.
Нажмите на выше описанный метод POST
. Он должен вызывать вспомогательные окна, имеющие вкладки. Перейдите на вкладку Headers
. На этой странице перечислены заголовки запросов, в значительной степени идентификационные данные, которые другая сторона (например, сайт) нуждается в вас, чтобы иметь возможность подключиться (кто-то может объяснить этот muuuch лучше, чем я).
Всякий раз, когда URL-адрес имеет переменные, такие как номера страниц, маркеры местоположений или категории, чаще всего это не так, сайт использует строки запросов. Короткий длинный рассказ похож на SQL-запрос (на самом деле это SQL-запрос, иногда), который позволяет сайту извлекать нужную вам информацию. Если это так, вы можете проверить заголовки запросов для параметров строки запроса. Прокрутите вниз немного, и вы должны его найти.
Как вы можете видеть, параметры строки запроса соответствуют переменным в нашем URL-адресе. Немного ниже, вы можете видеть Form Data
с pageNum: 2
под ним. Это ключ.
POST
запросы чаще известны как запросы формы, потому что это те запросы, которые были сделаны при отправке форм, регистрации на веб-сайтах и т.д. В принципе, практически все, что вам нужно, чтобы отправлять информацию. Большинство людей не видят, что запросы POST
имеют URL-адрес, за которым они следуют. Хорошим примером этого является, когда вы входите в систему на веб-сайт и, очень кратко, видите, что ваш адресный бар превращается в какой-то талисманный URL-адрес перед тем, как установить /index.html
или somesuch.
В основном это означает, что вы можете (но не всегда) добавлять данные формы к своему URL-адресу, и он выполнит запрос POST
для вас при выполнении. Чтобы узнать точную строку, которую вы должны добавить, нажмите view source
.
Проверьте, работает ли он, добавив его в URL.
Эт вуаля, это работает. Теперь реальная проблема: автоматическая загрузка последней страницы и очистка всех страниц. Ваш код в значительной степени присутствует. Единственное, что нужно сделать, это получить количество страниц, составить список URL-адресов для очистки и повторить их.
Измененный код ниже:
from bs4 import BeautifulSoup as bsoup
import requests as rq
import re
base_url = 'http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY'
r = rq.get(base_url)
soup = bsoup(r.text)
# Use regex to isolate only the links of the page numbers, the one you click on.
page_count_links = soup.find_all("a",href=re.compile(r".*javascript:goToPage.*"))
try: # Make sure there are more than one page, otherwise, set to 1.
num_pages = int(page_count_links[-1].get_text())
except IndexError:
num_pages = 1
# Add 1 because Python range.
url_list = ["{}&pageNum={}".format(base_url, str(page)) for page in range(1, num_pages + 1)]
# Open the text file. Use with to save self from grief.
with open("results.txt","wb") as acct:
for url_ in url_list:
print "Processing {}...".format(url_)
r_new = rq.get(url_)
soup_new = bsoup(r_new.text)
for tr in soup_new.find_all('tr', align='center'):
stack = []
for td in tr.findAll('td'):
stack.append(td.text.replace('\n', '').replace('\t', '').strip())
acct.write(", ".join(stack) + '\n')
Мы используем регулярные выражения для получения правильных ссылок. Затем, используя понимание списка, мы создали список строк URL. Наконец, мы перебираем их.
Результаты:
Processing http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY&pageNum=1...
Processing http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY&pageNum=2...
Processing http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY&pageNum=3...
[Finished in 6.8s]
Надеюсь, что это поможет.
EDIT:
Из чистой скуки, я думаю, я просто создал скребок для всего каталога классов. Кроме того, я обновляю оба выше и ниже кода, чтобы не выходить из строя, когда доступна только одна страница.
from bs4 import BeautifulSoup as bsoup
import requests as rq
import re
spring_2015 = "http://my.gwu.edu/mod/pws/subjects.cfm?campId=1&termId=201501"
r = rq.get(spring_2015)
soup = bsoup(r.text)
classes_url_list = [c["href"] for c in soup.find_all("a", href=re.compile(r".*courses.cfm\?campId=1&termId=201501&subjId=.*"))]
print classes_url_list
with open("results.txt","wb") as acct:
for class_url in classes_url_list:
base_url = "http://my.gwu.edu/mod/pws/{}".format(class_url)
r = rq.get(base_url)
soup = bsoup(r.text)
# Use regex to isolate only the links of the page numbers, the one you click on.
page_count_links = soup.find_all("a",href=re.compile(r".*javascript:goToPage.*"))
try:
num_pages = int(page_count_links[-1].get_text())
except IndexError:
num_pages = 1
# Add 1 because Python range.
url_list = ["{}&pageNum={}".format(base_url, str(page)) for page in range(1, num_pages + 1)]
# Open the text file. Use with to save self from grief.
for url_ in url_list:
print "Processing {}...".format(url_)
r_new = rq.get(url_)
soup_new = bsoup(r_new.text)
for tr in soup_new.find_all('tr', align='center'):
stack = []
for td in tr.findAll('td'):
stack.append(td.text.replace('\n', '').replace('\t', '').strip())
acct.write(", ".join(stack) + '\n')