Хобрук: Ваш путь к мастерству в программировании

Веб-скрапинг нескольких страниц форума с поисковым контентом

Я изо всех сил пытался получить список ссылок с нескольких страниц форума с контентом, выгруженным по страницам. Мой код работает хорошо (моя цель — выгрузить все разговоры для результата поиска в pdf), но не работает дальше первой страницы тредов. Когда я делаю быстрое сравнение источника страницы двух URL-адресов, я вижу проблему. Второй URL-адрес добавляет «#serp=2» и загружается правильно, но источник страницы тот же, что и ссылки с первой страницы.

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

#! python3
# getE2EResults.py - Opens all E2E threads and saves them to a file.

import requests, sys, webbrowser, bs4, pdfkit
from pypac import PACSession 
session = PACSession()
path_wkthmltopdf = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe'
config = pdfkit.configuration(wkhtmltopdf=path_wkthmltopdf)
site_list = []

print('Searching...') # display text while downloading 
res = session.get('http://e2e.ti.com/search?q=' + ''.join(sys.argv[1:]) + '&category=forum&date=&customdaterange=0&startdate=&enddate=')
res.raise_for_status()

# Retrieve top search result links.
soup = bs4.BeautifulSoup(res.text,'lxml')

# Find the number of pages in search results
mydivs = soup.findAll("div", {"class": "search-view-by-sort"})
string1 = mydivs[0].text
numberOfResults = [int(s) for s in string1.split() if s.isdigit()]
numberOfPages = (numberOfResults[0]//10)
if (numberOfResults[0]%10 > 0):
    numberOfPages += 1
print(str(numberOfPages) + ' pages of results')
###########################################

# Find all 10 post links for the first page, add to site list
linkElems = soup.select('.name a')
numOpen = min(10, len(linkElems))
for i in range(numOpen):
    res1 = session.get(linkElems[i].get('href'))
    res1.raise_for_status()
    site_list.append(linkElems[i].get('href'))
#   soup1 = bs4.BeautifulSoup(res1.text)
#   webbrowser.open(linkElems[i].get('href'))

# Repeat for all pages in search results
if (numberOfPages > 1):
    for n in range(2,(numberOfPages+1)):
        res = session.get('http://e2e.ti.com/search?q=' + ''.join(sys.argv[1:]) + '&category=forum&date=&customdaterange=0&startdate=&enddate=#serp='+str(n))
        #print('http://e2e.ti.com/search?q=' + ''.join(sys.argv[1:]) + '&category=forum&date=&customdaterange=0&startdate=&enddate=#serp='+str(n))
        res.raise_for_status()
        soup = bs4.BeautifulSoup(res.text,'lxml')
        linkElems = soup.select('.name a')
        numOpen = min(10, len(linkElems))
        for i in range(numOpen):
            res1 = session.get(linkElems[i].get('href'))
            res1.raise_for_status()
            site_list.append(linkElems[i].get('href'))

counter = 1
for item in site_list:
    print(str(counter) + ' ' + item)

'''         
# Create pdf of all Results
#print(site_list)
counter = 1
for item in site_list: 
  pdfkit.from_url(item, 'out'+str(counter)+'.pdf', configuration=config)
  counter += 1
#pdfkit.from_url(site_list, ''.join(sys.argv[1:])+'.pdf', configuration=config)
'''

  • Ваш вопрос касается программирования, и кажется, что это нормально, но сканирование данных форума может привести к нарушению авторских прав. 15.08.2018

Ответы:


1

Самый простой подход — найти URL-адрес следующей страницы и использовать его для следующего запроса. Когда кнопка отсутствует, вы знаете, что достигли последней страницы:

from bs4 import BeautifulSoup
import requests

def get_page_urls(html):
    soup = BeautifulSoup(html, 'lxml')

    # Find the number of pages in search results
    number_of_pages = int(soup.find(class_='search-view-by-sort').span.text.split(' ')[2].replace(',', '')) // 10

    # Find the URL for the next page
    next_url = soup.find('a', class_='next')

    if next_url:    
        next_url = base_url + next_url['href']

    # Display/store all of the links
    for link in soup.select('.name a'):
        site_list.append(link['href'])
        print(' ', link['href'])

    return number_of_pages, next_url


site_list = []
page_number = 1
jar = requests.cookies.RequestsCookieJar()
base_url = 'http://e2e.ti.com'
search = 'Beaglebone black'
url = '{}/search?q={}&category=forum&date=&customdaterange=0&startdate=&enddate='.format(base_url, search)

print("Page 1")
res = requests.get(url, cookies=jar)
number_of_pages, url = get_page_urls(res.text)    

while url:    
    page_number += 1
    print("Page {} of {}".format(page_number, number_of_pages))
    res = requests.get(url, cookies=jar)
    _, url = get_page_urls(res.text)    

Этот код продолжает запрашивать страницы и сохранять URL-адреса до тех пор, пока все страницы не будут получены. Обратите внимание, поиск жестко запрограммирован для тестирования.

Это даст вам результаты, начиная с:

Page 1
  http://e2e.ti.com/support/arm/sitara_arm/f/791/t/270719?tisearch=e2e-sitesearch&keymatch=Beaglebone black
  http://e2e.ti.com/support/embedded/linux/f/354/t/483988?tisearch=e2e-sitesearch&keymatch=Beaglebone black
  ..
  ..
Page 2 of 308
  http://e2e.ti.com/support/embedded/starterware/f/790/t/301790?tisearch=e2e-sitesearch&keymatch=Beaglebone black
  http://e2e.ti.com/support/arm/sitara_arm/f/791/t/501015?tisearch=e2e-sitesearch&keymatch=Beaglebone black
  ..
  ..
Page 3 of 308
  http://e2e.ti.com/support/embedded/starterware/f/790/p/285959/1050634?tisearch=e2e-sitesearch&keymatch=Beaglebone black#1050634
  ..
  ..
16.08.2018
  • Спасибо, Мартин! Я сейчас попробую. Сегодня я также наткнулся на другой способ вытащить ссылки с последующих страниц. Используя инструменты разработчика Chrome, я отслеживал сетевую активность, и когда запускается скрипт страницы, я просматривал заголовок, чтобы получить более подробный URL-адрес, на который он ссылался. Это долго и некрасиво, но когда я вставил URL-адрес с информацией о файлах cookie в свой код, я смог успешно извлечь ссылки со всех страниц. 17.08.2018
  • Только что попробовал - работает отлично. Спасибо еще раз! 17.08.2018
  • Новые материалы

    Учебные заметки JavaScript Object Oriented Labs
    Вот моя седьмая неделя обучения программированию. После ruby ​​и его фреймворка rails я начал изучать самый популярный язык интерфейса — javascript. В отличие от ruby, javascript — это более..

    Разбор строк запроса в vue.js
    Иногда вам нужно получить данные из строк запроса, в этой статье показано, как это сделать. В жизни каждого дизайнера/разработчика наступает момент, когда им необходимо беспрепятственно..

    Предсказание моей следующей любимой книги 📚 Благодаря данным Goodreads и машинному обучению 👨‍💻
    «Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг Эта статья сильно отличается от тех, к которым вы, возможно, привыкли . Мне очень понравилось поработать над..

    Основы принципов S.O.L.I.D, Javascript, Git и NoSQL
    каковы принципы S.O.L.I.D? Принципы SOLID призваны помочь разработчикам создавать надежные, удобные в сопровождении приложения. мы видим пять ключевых принципов. Принципы SOLID были разработаны..

    Как настроить Selenium в проекте Angular
    Угловой | Селен Как настроить Selenium в проекте Angular Держите свое приложение Angular и тесты Selenium в одной рабочей области и запускайте их с помощью Mocha. В этой статье мы..

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..