Mam indeksujący skrypt Pythona, który zawiesza się pod adresem URL: pulsepoint.com/sellers.json

Bot używa standardowego żądania, aby pobrać zawartość, ale zwraca błąd 404. W przeglądarce działa (jest przekierowanie 301, ale żądanie może następować po nim). Moje pierwsze przeczucie jest takie, że może to być problem z nagłówkiem żądania, więc skopiowałem konfigurację przeglądarki. Kod wygląda następująco

        crawled_url="pulsepoint.com"
        seller_json_url = 'http://{thehost}/sellers.json'.format(thehost=crawled_url)
        print(seller_json_url)
        myheaders = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'Accept-Language': 'fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3',
                'Accept-Encoding': 'gzip, deflate, br',
                'Connection': 'keep-alive',
                'Pragma': 'no-cache',
                'Cache-Control': 'no-cache'
            }
        r = requests.get(seller_json_url, headers=myheaders)
        logging.info("  %d" % r.status_code)

Ale nadal otrzymuję błąd 404.

Moje następne przypuszczenie:

  • Zaloguj sie? Nie używany tutaj
  • Ciasteczka? Nie to, żebym widział

Jak więc ich serwer blokuje mojego bota? Nawiasem mówiąc, to jest adres URL, który ma być indeksowany, nic nielegalnego.

Z góry dziękuję!

0
Ben Banks 1 kwiecień 2020, 23:03

3 odpowiedzi

Najlepsza odpowiedź

Możesz również obejść błąd certyfikatu SSL, jak poniżej:

from urllib.request import urlopen
import ssl
import json

#this is a workaround on the SSL error
ssl._create_default_https_context = ssl._create_unverified_context
crawled_url="pulsepoint.com"
seller_json_url = 'http://{thehost}/sellers.json'.format(thehost=crawled_url)
print(seller_json_url)

response = urlopen(seller_json_url).read() 
# print in dictionary format
print(json.loads(response)) 

Przykładowa odpowiedź:

{'contact_email': 'PublisherSupport@pulsepoint.com', 'contact_address': '360 Madison Ave, 14th Floor, NY, NY, 10017', 'version': '1.0', 'identifiers': [{'name': 'TAG-ID', 'value': '89ff185a4c4e857c'}], 'sellers': [{'seller_id': '508738', ...

... 'typ_sprzedawcy': 'WYDAWCA'}, {'identyfikator_sprzedawcy': '562225', 'nazwa': 'EL DIARIO', 'domena': 'impremedia.com', 'typ_sprzedawcy': 'WYDAWCA'}]}

1
âńōŋŷXmoůŜ 2 kwiecień 2020, 15:49

Ok, tylko dla innych, zahartowana wersja odpowiedzi âńōŋŷXmoůŜa, bo:

  • Niektóre witryny chcą, aby nagłówki odpowiadały;
  • Niektóre witryny używają dziwnego kodowania
  • Niektóre witryny wysyłają odpowiedzi spakowane gzipem, gdy nie są wymagane.
    import urllib
    import ssl
    import json
    from io import BytesIO
    import gzip

    ssl._create_default_https_context = ssl._create_unverified_context
    crawled_url="pulsepoint.com"
    seller_json_url = 'http://{thehost}/sellers.json'.format(thehost=crawled_url)
    req = urllib.request.Request(seller_json_url)
    # ADDING THE HEADERS
    req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0')
    req.add_header('Accept','application/json,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8')

    response = urllib.request.urlopen(req)
    data=response.read()
    # IN CASE THE ANSWER IS GZIPPED
    if response.info().get('Content-Encoding') == 'gzip':
        buf = BytesIO(data)
        f = gzip.GzipFile(fileobj=buf)
        data = f.read()
    # ADAPTS THE ENCODING TO THE ANSWER
    print(json.loads(data.decode(response.info().get_param('charset') or 'utf-8')))

Dzięki jeszcze raz!

0
Ben Banks 3 kwiecień 2020, 10:06

Możesz po prostu przejść bezpośrednio do linku i wyodrębnić dane, nie ma potrzeby, aby uzyskać 301 do prawidłowego linku

import requests
headers = {"Upgrade-Insecure-Requests": "1"}
response = requests.get(
    url="https://projects.contextweb.com/sellersjson/sellers.json",
    headers=headers,
    verify=False,
)

0
nikoola 1 kwiecień 2020, 20:18