Как очистить несколько результатов, имеющих одинаковые теги и класс - PullRequest
0 голосов
/ 06 марта 2020

Мой код является точным для одной страницы, но когда я запускаю этот код для нескольких записей, используя для l oop, и если некоторые данные отсутствуют, например, для человека (как я использовал индекс № [1] и [2] для человека переменная, местоположение, номер телефона и номер ячейки, но если чего-то не хватает, например, отсутствует имя человека) следующая запись будет извлечена из переменной person. Не могли бы вы исправить эту проблему? вот мой код:

import requests
from bs4 import BeautifulSoup
import re


def get_page(url):
    response = requests.get(url)
    if not response.ok:
        print('server responded:', response.status_code)
    else:
        soup = BeautifulSoup(response.text, 'lxml') # 1. html , 2. parser
    return soup

def get_detail_data(soup):
        #soup = BeautifulSoup(r.text, 'html.parser')
        try:
            title = soup.find("h1", {'class': 'sc-AykKI'}).text
        except:
            title = 'Empty Title'
        #print(title)
        try:
            person = soup.find(
            "span", {'class': 'Contact__Item-sc-1giw2l4-2 kBpGee'}).text.strip()
        except:
            person = 'Empty Person'
        #print(person)
        try:
            addr = soup.findAll(
            "span", {'class': 'Contact__Item-sc-1giw2l4-2 kBpGee'})[1].text
        except:
            addr = 'Empty Address'
        #print(addr)
        #abn = soup.find('div', class_="box__Box-sc-1u3aqjl-0 kxddET").('a').text
        #print(abn)
        try:
            ratting = soup.find(
            "div", {'class': 'Rating__RatingText-sc-1r9ytu8-1 jIdgkl'}).text
        except:
            ratting = 'Empty Ratting'
        #print(ratting)
        try:
            abn = (re.search('abn\\\\":\\\\"(.*?)\\\\"', soup.text).group(1))
        except:
            abn = 'Empty ABN'
        #print(abn)
        try:
            website = (re.search('website\\\\":\\\\"(.*?)\\\\"', soup.text).group(1))
        except:
            website = 'Empty Website'
        #print(website )
        try:
            phone = (re.search('phone\\\\":\\\\"(.*?)\\\\"', soup.text).group(1))
        except:
            phone = 'Empty Phone No'
        #print(phone)
        try:
            cell = (re.search('mobile\\\\":\\\\"(.*?)\\\\"', soup.text).group(1))
        except:
            cell = 'Empty Cell No'
        #print(cell)

        data = {
        'title'         : title,
        'peron name'    : person,
        'address'       : addr,
        'phone no'      : phone,
        'cell no'       : cell,
        'abn no'        : abn,
        'website'       : website
        }
        return data
def get_index_data(soup):
    #soup = BeautifulSoup(r.text, 'html.parser')
    titles = []
    for item in soup.findAll("h3", {'class': 'sc-bZQynM sc-iwsKbI dpKmnV'}):
        urls = (f"https://hipages.com.au{item.previous_element.get('href')}")
        titles.append(urls)
    #print(titles)
    return titles

def Main():
    url = "https://hipages.com.au/connect/abcelectricservicespl/service/126298"
    mainurl = "https://hipages.com.au/find/antenna_services/nsw/sydney"
    main_titles = get_index_data(get_page(mainurl))
    for title in main_titles:
        data1 = get_detail_data(get_page(title))
        print(data1)


Main()

1 Ответ

0 голосов
/ 07 марта 2020

Вам нужно анализировать данные из тега сценария, а не через span и div.

Попробуйте это:

import requests
from bs4 import BeautifulSoup
import re
import pandas as pd
from pandas import json_normalize
import json

def get_page(url):
    response = requests.get(url)
    if not response.ok:
        print('server responded:', response.status_code)
    else:
        soup = BeautifulSoup(response.text, 'lxml') 
    return soup

def get_detail_data(url):
    res = requests.get(url)
    soup = BeautifulSoup(res.content, "lxml")
    raw = res.text.split("<script> window.__INITIAL_STATE__=")[1]
    raw = raw.split("</script>")[0]
    data = json.loads(raw)
    data = json.loads(data)

    cols = ['abn', 'address', 'name', 'primary_location', 'service_area', 'state', 'suburb', 'website']

    df = pd.DataFrame(data["sites"]["list"]).T
    df = df[cols].reset_index(drop=True)

    primary_location = json_normalize(df.primary_location[0])
    df = pd.concat([df, primary_location], axis=1)
    to_drop = ["primary_location", "is_primary", "suburb_seo_key", "capital_city_seo_key"]
    df.drop(to_drop, axis=1, inplace=True)

    return df


def get_index_data(soup):
    titles = []
    for item in soup.findAll("h3", {'class': 'sc-bZQynM sc-iwsKbI dpKmnV'}):
        urls = (f"https://hipages.com.au{item.previous_element.get('href')}")
        titles.append(urls)
    return titles

def Main():
    mainurl = "https://hipages.com.au/find/antenna_services/nsw/sydney"
    main_titles = get_index_data(get_page(mainurl))  
    final_data = [] 
    for title in main_titles:
        data = get_detail_data(title)
        final_data.append(data)
    return final_data

data = Main()

df = pd.concat(data).reset_index(drop=True)
display(df)

Кстати, это дает вам гораздо более подробные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...