Python - pomoc - znajdowanie najmłodszych rekordów

Python - pomoc - znajdowanie najmłodszych rekordów
NO
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:25
0

Cześć, bardzo proszę o pomoc.

To wypluwa mój kod:
screenshot-20200922180508.png

Do jednego rekordu wypluwa mi kilka adresów url, a ja chciałbym tylko ten, który jest najmłodszy według aktulnosc lub aktualnosc rok.

Jakiś pomysl? Bede bardzo wdzięczny

edytowany 1x, ostatnio: Ktos
lion137
Wklej kod na forum w znaczniki, opisz dokładniej problem i gdzie szukałeś rozwiązania.
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:10 minut
1

Żadnego tekstu nie wkleja się jako zdjęcia/screenshota na forum!
bo:

  1. nikt nie będzie przepisywał kodu (albo robić OCR), żeby ci pomóc
  2. nie ma jak poprawić kodu
  3. nie da się wyszukiwać
  4. Niektórzy siedzą za firewall-em i mogą nie widzieć obrazków (szczególnie jeśli są na dziwnym serwerze)
  5. nie można sprawdzić, czy używasz jakiś dziwnych znaków

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22
TS
  • Rejestracja:prawie 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:394
0

Jest jakiś regexp tylko nie wiadomo, co tam się właściwie maczuje.

Pipes
  • Rejestracja:około 11 lat
  • Ostatnio:ponad 3 lata
  • Postów:459
8

title

  • odp.PNG (7 KB) - ściągnięć: 261
edytowany 1x, ostatnio: Pipes
NO
  • Rejestracja:ponad 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:25
1

Przepraszam bardzo za kłopot, już się poprawiam, przepraszam z całego serca.

Co chciałbym osiągnąć:

  1. Chciałbym aby pętla, która znajduję się na końcu dodawała wybrane matche do listy new_text. Niestety dodaje tylko tylko pierwszy, jestem pewny, że po prostu powinno to znajdować się w innym miejscu, bo z każdym requestem tworzy się nowa lista, a ja nie potrafię tego miejsca zlokalizować.
  2. Wybrane tzn, najmłodszy. Dla każdego rekordu, w tym przypadku dla 5, zwraca kilka adresów url, a ja chciałym tylko ten najmłodszy według 'aktualnosc' lub 'aktualnoscRok'.
  3. ' if row_num >5 : break # for testing, get first n rows' Ostatecznie będę to usuwał i kod będzie przechodził przez 101 tyś rekordów, chciałbym jakaś prostą logikę, która w momencie odmowy dostępu napiszę błąd i poczeka 10 sekund.

Bardzo proszę o pomoc i pozdrawiam!

Kopiuj
# libraries
import re
import requests
import shapefile
import pandas as pd

#shapefile
shapefile_path = 'C:/Users/ja/PYTHON SPYDER/Python praca/shapefiles/PL1992_5000_025'

# wms
wms_request_base_url = 'https://mapy.geoportal.gov.pl/wss/service/PZGIK/ORTO/WMS/SkorowidzeWgAktualnosci'
wms_request_parameters = {
    'SERVICE': 'WMS',
    'request': 'GetFeatureInfo',
    'version': '1.3.0',
    'layers': 'SkorowidzeOrtofotomapyStarsze,SkorowidzeOrtofotomapy2018,SkorowidzeOrtofotomapy2019,SkorowidzeOrtofotomapy2020',
    'styles': '',
    'crs': 'EPSG:2180',
    'width': 1000,
    'height': 1000,
    'format': 'image/png',
    'transparent': 'true',
    'query_layers': 'SkorowidzeOrtofotomapyStarsze,SkorowidzeOrtofotomapy2018,SkorowidzeOrtofotomapy2019,SkorowidzeOrtofotomapy2020',
    'i': 1,
    'j': 1,
    'INFO_FORMAT': 'text/html'
}
regexp = '{url:"(.+)",godlo:"(.+)", aktualnosc:"(.+)", wielkoscPiksela:"(.+)", ukladWspolrzednych:"(.+)", calyArkuszWyeplnionyTrescia:"(.+)", modulArchiwizacji:"(.+)", zrodloDanych:"(.+)", kolor:"(.+)", numerZgloszeniaPracy:"(.+)", aktualnoscRok:"(.+)"}'
compiled_regexp = re.compile(regexp, re.IGNORECASE)
attribute_names = [
    'url',
    'godlo',
    'aktualnosc',
    'wielkoscPiksela',
    'ukladWspolrzednych',
    'calyArkuszWyeplnionyTrescia',
    'modulArchiwizacji',
    'zrodloDanych',
    'kolor',
    'numerZgloszeniaPracy',
    'aktualnoscRok'
]

if __name__ == '__main__':

    # open shape file
    with shapefile.Reader(shapefile_path) as shp:
        total_rows = shp.numRecords

        # for each record in the shapefile (we are ignoring geometry here)
        for row_num, row in enumerate(shp.iterRecords()):
            # -----------------------------------------------------
            # remove before production use:
            if row_num >5 : break  # for testing, get first n rows
            # -----------------------------------------------------

            # get row as dict so we have attribute names
            r = row.as_dict()

            # create bounding box
            minx = min(r['x1'], r['x2'], r['x3'], r['x4'])
            miny = min(r['y1'], r['y2'], r['y3'], r['y4'])
            maxx = max(r['x1'], r['x2'], r['x3'], r['x4'])
            maxy = max(r['y1'], r['y2'], r['y3'], r['y4'])
            bbox = [minx, miny, maxx, maxy]
            # create comma separated string representation of bbox that we will use for the HTTP request to WMS service
            bbox_str = ','.join([str(el) for el in bbox])
            wms_request_parameters['bbox'] = bbox_str

            print(f'{str(row_num+1).zfill(6)}/{total_rows}', '- godło:', r['godlo'], '- bbox:', bbox)

            # make the HTTP request
            new_text = [] 
            response = requests.get(wms_request_base_url, params=wms_request_parameters)      
            if response.ok:
                # construct dictionary with data parsed from http response using regular expressions
                for matches in compiled_regexp.findall(response.text):
                    record = {name: value for name, value in zip(attribute_names, matches)}
                    new_text.append(record)
             
                    
print(new_text)
# table = pd.DataFrame(text)
# table.to_excel(r'C:/Users/ja/linki.xlsx', index = True)
                        
                        



    
        
                    
           
                    
                    
                    
                    
                    
                    
                    
                    
                    

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:10 minut
1

Człowieku, dostajesz w odpowiedzi JSona, więc ten regexp jest zagrożeniem dla zdrowia psychicznego.

Kopiuj
            response = requests.get(wms_request_base_url, params=wms_request_parameters)      
            if response.ok:
                json = response.json()
                new_text = new_text + json

Dobra rada naucz się dzielić kod na funkcje, będzie większa szansa zrozumienia co twój kod robi/ma robić. Nie masz ani jednej!


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
AF
  • Rejestracja:prawie 7 lat
  • Ostatnio:14 dni
  • Postów:172
0

^ nie używaj regexa do parsowania jsona. Jeżeli dostajesz xml to tym bardziej, sparsuj xml istniejącymi bibliotekami.

Co do pytań:

  1. Inicjalizujesz new_text w 73 linijce więc przy każdej iteracji inicjalizujesz na nowo. Jak chcesz zachować wyniki to wyniesć inicjalizację przed for loopem.
  2. Jak wygląda pełna odpowiedź? Wklej jsona/xml. Ale powinno to być proste jeżeli sparsujesz do struktur - wybrać po prostu strukturę wedle założonego parametru.
  3. Jak w poście @MarekR22 , jeżeli nie masz response.ok to dodaj logikę jaką chcesz (jak sleep). Jeżeli API, z którego korzystasz ma ograniczenia np. ilość requestów na godzinę dobrze byłoby uwzględnić to w kodzie. Są do tego gotowe biblioteki jak ratelimit .

Edit bo spojrzałem na screen w pierwszym poście, i widzę że w odpowiedzi dostajesz listę dictów z urlami. Rozszerzając 2. odpowiedź na przykładzie:

Kopiuj
resp = [{'url': '1', 'aktualnosc': '2019/08/31'}, {'url': '2', 'aktualnosc': '2019/10/2'}, {'url': '3', 'aktualnosc': '2020/01/14'}]
recent = max(resp, key=lambda x: x['aktualnosc'])

Datę powinno raczej się parsować do obiektu datetime i na tej podstawie porównywać ale dzięki formatowi rok/miesiąc/dzień porównanie stringa powinno też zadziałać. Przy wielu rekordach i różnych operacjach pomocna może też być biblioteka pandas.

edytowany 1x, ostatnio: AsterFV

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.