WedX - журнал о программировании и компьютерных науках

Веб-скрапинг нескольких похожих страниц

Я новичок в парсинге веб-страниц на python, и я пытался взять адреса разных мест winmar в Канаде, а также поместить результаты в файл csv. До сих пор единственный способ, которым я нашел различие между сайтами разных местоположений, — это код в конце адреса (цифры). Проблема в том, что результаты не меняются во время работы программы, а вместо этого выдают результаты первого местоположения (305) при печати и в файле csv. Спасибо за ваше время и внимание!

Вот мой код:

import csv
import requests
from bs4 import BeautifulSoup

x = 0
numbers = ['305', '405', '306', '307', '308', '309', '4273']

f = csv.writer(open('Winmar_locations.csv', 'w'))
f.writerow(['City:', 'Address:'])

for links in numbers:

    for x in range(0, 6):
        url = 'https://www.winmar.ca/find-a-location/' + str(numbers[x])
        r = requests.get(url)
        soup = BeautifulSoup(r.content, "html.parser")

    location_name = soup.find("div", attrs={"class": "title_block"})
    location_name_items = location_name.find_all('h2')

    location_list = soup.find(class_='quick_info')
    location_list_items = location_list.find_all('p')

    for name in location_name_items:
        names = name.text
        names = names.replace('Location | ', '')

    for location in location_list_items:
        locations = location.text.strip()
        locations = locations.replace('24 Hour Emergency | (902) 679-1116','')

    print(names, locations)
    x = x+1

    f.writerow([names, locations])

Ответы:


1

У вас было несколько неправильных вещей в вашем коде и одна вещь о веб-сайте, который вы очищаете.

  • Первый доступ к такому URL-адресу https://www.winmar.ca/find-a-location/308 не изменит местоположение должным образом, он должен быть таким https://www.winmar.ca/find-a-location/#308 с хэш-бангом перед номером.

  • На веб-сайте есть дублированный html с одними и теми же классами, это означает, что у вас почти все местоположения загружены все время, и они просто выбирают, что показывать из своего кода js - плохая практика, конечно, что заставляет ваш сопоставитель всегда получать одно и то же местоположение, что объясняет почему у вас всегда повторялось одно и то же место.

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

вот модифицированная версия вашего кода

import csv
import requests
from bs4 import BeautifulSoup

x = 0
numbers = ['305', '405', '306', '307', '308', '309', '4273']


names = []
locations = []
for x in range(0, 6):
    url = 'https://www.winmar.ca/find-a-location/#' + str(numbers[x])
    print(f"pinging url {url}")

    r = requests.get(url)
    soup = BeautifulSoup(r.content, "html.parser")
    scope = soup.find(attrs={"data-id": str(numbers[x])})

    location_name = scope.find("div", attrs={"class": "title_block"})
    location_name_items = location_name.find_all('h2')


    location_list = scope.find(class_='quick_info')
    location_list_items = location_list.find_all('p')

    name = location_name.find_all("h2")[0].text
    print(name)

    names.append(name)

    for location in location_list_items:
        loc = location.text.strip()
        if '24 Hour Emergency' in loc: 
            continue
        print(loc)
        locations.append(loc)

    x = x+1

Обратите внимание на обзор, который я сделал

    scope = soup.find(attrs={"data-id": str(numbers[x])})

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

это приводит к:

pinging url https://www.winmar.ca/find-a-location/#305
Location | Annapolis
70 Donald E Hiltz Connector Road
Kentville, NS
B4N 3V7
pinging url https://www.winmar.ca/find-a-location/#405
Location | Bridgewater
15585 Highway # 3
Hebbville, NS
B4V 6X7
pinging url https://www.winmar.ca/find-a-location/#306
Location | Halifax
9 Isnor Dr
Dartmouth, NS
B3B 1M1
pinging url https://www.winmar.ca/find-a-location/#307
Location | New Glasgow
5074 Hwy. #4, RR #1
Westville, NS
B0K 2A0
pinging url https://www.winmar.ca/find-a-location/#308
Location | Port Hawkesbury
8 Industrial Park Rd
Lennox Passage, NS
B0E 1V0
pinging url https://www.winmar.ca/find-a-location/#309
Location | Sydney
358 Keltic Drive
Sydney River, NS
B1R 1V7

12.04.2020
  • Большое спасибо! Я не знал этого о сайте. Спасибо за подробное объяснение, даже не знаю, как вам благодарить! Хорошего дня. 12.04.2020

  • 2

    Хотя у вас есть квалифицированный ответ, я подумал придумать свой. Я постарался сделать сценарий лаконичным, избавившись от многословия. Убедитесь, что ваша версия bs4 4.7.0 или более поздняя, ​​чтобы она поддерживала псевдоселектор, который я определил в скрипте для поиска адреса.

    import csv
    import requests
    from bs4 import BeautifulSoup
    
    base = 'https://www.winmar.ca/find-a-location/#{}'
    
    numbers = ['305', '405', '306', '307', '308', '309', '4273']
    
    with open("Winmar_locations.csv","w",newline="") as f:
        writer = csv.writer(f)
        writer.writerow(['City','Address'])
    
        while numbers:
            num = numbers.pop(0)
            r = requests.get(base.format(num))
            soup = BeautifulSoup(r.content,"html.parser")
    
            location_name = soup.select_one(f"[data-id='{num}'] .title_block > h2.title").contents[-1]
            location_address = soup.select_one(f"[data-id='{num}'] .heading:contains('Address') + p").get_text(strip=True)
            writer.writerow([location_name,location_address])
            print(location_name,location_address)
    
    12.04.2020
  • Большое спасибо за ваше решение, я обязательно попробую оба, когда у меня будет возможность (у меня мобильный банкомат). Спасибо и хорошего дня! 12.04.2020
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

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

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]