Веб-очистка Python, как зациклить все страницы/следующую страницу

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

import pandas as pd
pd.options.mode.chained_assignment = None  # default='warn'  # to suppress "false positive" warnings
import datetime as dt
import requests
from bs4 import BeautifulSoup
import time



def getPage(url):
    attempt = 1
    while True:
        response = requests.get(url)
        if response.status_code == requests.codes.ok:
            return response.content
        else:
            time.sleep(0.5)
            attempt += 1
            if attempt > 3:
                print("Data could not be requested for url:  ", url, "  after  ", attempt, "  attempts")
                return None



if __name__ == '__main__':


    url = "https://www.opic.com/upphandlingar/"

    data_df = pd.DataFrame()  # all data from the websites is saved to this data frame
    # get data
    try:
        markup = getPage(url).decode('utf-8')
    except:
        markup = getPage(url)


    if markup is None:
        print("Nothing was found. Value of 'markup' is 'None'.")
        sys.exit()

    soup = BeautifulSoup(markup, 'lxml')

    containers = soup.findAll("a", {"class": "ListItem"})
    for container in containers:
        upplagtdatum = container.div.p.text.strip()
        titel = container.h3.text.strip()
        stad_kommun = container.span.text.strip()



        # ----------------------------------------------------------------------------------------------------------
        # Save data to data frame
        df = pd.DataFrame(data = {'Upplagtdatum': [upplagtdatum], 'Titel': [titel], 'Stad Kommun': [stad_kommun]})
        data_df = pd.concat([data_df, df], sort=False)


    #   SAVE DATA

    # Save data frame to csv-file

    filePathName = "data_" + dt.datetime.now().strftime('%Y-%m-%d') + ".csv"
    data_df.to_csv(filePathName, sep=';', index=False, encoding='utf-8')


    print(data_df)

import pandas as pd
pd.options.mode.chained_assignment = None  # default='warn'  # to suppress "false positive" warnings
import datetime as dt
import requests
from bs4 import BeautifulSoup
import time

def getPage(url):
    attempt = 1
    while True:
        response = requests.get(url)
        if response.status_code == requests.codes.ok:
            return response.content
        else:
            time.sleep(0.5)
            attempt += 1
            if attempt > 3:
                print("Data could not be requested for url:  ", url, "  after  ", attempt, "  attempts")
                return None

if __name__ == '__main__':

 url = "https://www.opic.com/upphandlingar/"

    data_df = pd.DataFrame()  # all data from the websites is saved to this data frame
    # get data
    try:
        markup = getPage(url).decode('utf-8')
    except:
        markup = getPage(url)


    if markup is None:
        print("Nothing was found. Value of 'markup' is 'None'.")
        sys.exit()

    soup = BeautifulSoup(markup, 'lxml')

    containers = soup.findAll("a", {"class": "ListItem"})
    for container in containers:
        upplagtdatum = container.div.p.text.strip()
        titel = container.h3.text.strip()
        stad_kommun = container.span.text.strip()

 # Save data to data frame
        df = pd.DataFrame(data = {'Upplagtdatum': [upplagtdatum], 'Titel': [titel], 'Stad Kommun': [stad_kommun]})
        data_df = pd.concat([data_df, df], sort=False)

filePathName = "data_" + dt.datetime.now().strftime('%Y-%m-%d') + ".csv"
    data_df.to_csv(filePathName, sep=';', index=False, encoding='utf-8')


    print(data_df)

Можете ли вы добавить дополнительную информацию к вашему вопросу? Таким образом, вы также можете правильно отформатировать свой код, а не публиковать его в виде обычного текста.

Snackoverflow 07.05.2019 11:47

Пожалуйста, отформатируйте код правильно и опишите конкретно, что вы хотите получить и что вы получаете взамен. Включите только код, необходимый и достаточный для вопроса. Прочтите stackoverflow.com/help/mcve

aparpara 07.05.2019 11:50
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
606
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Глядя на веб-сайт и предоставленный вами код, я предполагаю, что вы хотите извлечь атрибут href из всех полученных вами ListItem (контейнеров). Вы можете просто получить href следующим образом: (при условии, что у вас есть BeautifulSoup4)

    for container in containers:
        upplagtdatum = container.div.p.text.strip()
        titel = container.h3.text.strip()
        stad_kommun = container.span.text.strip()
        href = container.get('href')

Затем вы можете либо использовать этот href немедленно, либо сохранить его в своем DataFrame, чтобы просмотреть его позже.

то, что я пытаюсь сделать, это очистить другие разные страницы, потому что я могу очистить первую страницу, но, похоже, не могу написать код, который продолжает очищать другие страницы с той же информацией (кнопка «Далее»)

scrapemm 07.05.2019 16:34
Ответ принят как подходящий

Я сделал некоторые изменения в вашем коде. Используя это форматирование, вы можете добиться разбиения на страницы.

import pandas as pd
pd.options.mode.chained_assignment = None  # default='warn'  # to suppress "false positive" warnings
import datetime as dt
import requests
from bs4 import BeautifulSoup
import time
import sys

def getPage(url):
    attempt = 1
    while True:
        response = requests.get(url)
        if response.status_code == requests.codes.ok:
            return response.content
        else:
            time.sleep(0.5)
            attempt += 1
            if attempt > 3:
                print("Data could not be requested for url:  ", url, "  after  ", attempt, "  attempts")
                return None

def getData(markup):
    data_df = pd.DataFrame()  # all data from the websites is saved to this data frame
    soup = BeautifulSoup(markup, 'lxml')
    containers = soup.findAll("a", {"class": "ListItem"})
    for container in containers:
        upplagtdatum = container.div.p.text.strip()
        titel = container.h3.text.strip()
        stad_kommun = container.span.text.strip()

        # ----------------------------------------------------------------------------------------------------------
        # Save data to data frame
        df = pd.DataFrame(data = {'Upplagtdatum': [upplagtdatum], 'Titel': [titel], 'Stad Kommun': [stad_kommun]})
        data_df = pd.concat([data_df, df], sort=False)

    #   SAVE DATA
    # Save data frame to csv-file
    filePathName = "data_" + dt.datetime.now().strftime('%Y-%m-%d') + ".csv"
    data_df.to_csv(filePathName, sep=';', index=False, encoding='utf-8')
    print(data_df)

if __name__ == '__main__':
    results = 2871
    per_page = 20
    url = "https://www.opic.com/upphandlingar/?p = {}"
    no_of_pages = int(results/per_page)
    for page_no in range(1,no_of_pages + 1):
        try:
            markup = getPage(url.format(page_no)).decode('utf-8')
        except:
            markup = getPage(url)

        if markup is None:
            print("Nothing was found. Value of 'markup' is 'None'.")
            sys.exit()
        else:
            getData(markup)

Объяснение

  • Каждая страница имеет одинаковую структуру шаблона/страницы, поэтому вам нужна функция для извлечения необходимого содержимого.
  • Разбивка на страницы, как формируется следующая страница, здесь, если вы видите, что параметр URL р= добавляется в URL.
  • Сколько страниц? Это зависит от того, сколько всего результатов и сколько на странице. Если вы выясните, просто сделайте карту и повторите ее.

Посмотрите на код, обновите его, если нужно.

когда я пробую этот код, я получаю сообщение об ошибке. Данные не могут быть запрошены для URL-адреса: opic.com/upphandlingar/?p=0 после 4 попыток Данные не могут быть запрошены для URL-адреса: opic.com/upphandlingar/?p={} после 4 попыток. Ничего не найдено. Значение «наценка» равно «Нет».

scrapemm 08.05.2019 10:06

Ошибка из-за отсутствия 0-й страницы. Он начинается с индекса 1. Я немного меняю код. Т.е. opic.com/upphandlingar/?p=1 не из opic.com/upphandlingar/?p=0. Код изменен здесь for page_no in range(1,no_of_pages + 1)

Dhamodharan 08.05.2019 10:45

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

scrapemm 08.05.2019 12:11

Кажется, вы записываете данные в один и тот же файл. Попробуйте сделать его динамичным. Если вы проверите код, я инициализировал фрейм данных в функции getData на основе вашего кода, он сохранит несколько файлов csv. Или вы можете объявить один CSV-файл и добавить к нему данные. Надеюсь, это решит вашу проблему, не забудьте проголосовать :)

Dhamodharan 08.05.2019 15:25

Я довольно новичок в кодировании, как мне сохранить разные страницы, извините, если я вас беспокою ..

scrapemm 08.05.2019 18:18

Без проблем! Я добавил простой пример поверх здесь.

Dhamodharan 09.05.2019 11:11

где я могу поместить это в мой код, который немного запутался, когда я пытался это сделать:/

scrapemm 09.05.2019 11:44

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

Dhamodharan 09.05.2019 14:40

Другие вопросы по теме