Dlaczego nie mogę curl pobrać tego linku, gdy przeglądarka to zrobi?

30

Używam Mac OS 10.11.6 El Capitan. Jest link, który chciałbym pobrać programowo:

https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg

Jeśli wkleję ten adres URL do dowolnej przeglądarki (np. Safari), pobieranie działa idealnie.

Jeśli jednak spróbuję pobrać ten sam adres URL z wiersza polecenia przy użyciu curl, to nie zadziała - wynikiem będzie pusty plik:

$ ls -lA
$ curl -O https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
$ ls -lA
total 0
-rw-r--r--  1 myname  staff  0 Nov  7 14:07 mysql-5.7.16-osx10.11-x86_64.dmg
$ 

Oczywiście mogę pobrać plik za pośrednictwem przeglądarki, ale chciałbym zrozumieć, dlaczegocurl komenda powyżej nie działa.

Dlaczego nie można curlpoprawnie pobrać tego pliku, skoro jest on wyraźnie widoczny na stronie internetowej i można go poprawnie wyświetlić i pobrać za pomocą graficznej przeglądarki internetowej?

mattobob
źródło
7
Chciałbym zauważyć, że chociaż odpowiedź techraf na przekierowania jest całkowicie poprawna, inne czynniki, takie jak nagłówki, mogą spowodować, że serwer odrzuci prośbę klienta curl o pobranie pliku. Na przykład, jeśli serwer ma wewnętrzną ochronę DDoS, takie oprogramowanie zabezpieczające zwykle sprawdza, czy istnieją realne nagłówki przeglądarki, takie jak posiadanie odpowiedniego User-Agent. Ponadto niektóre pliki do pobrania przeglądarki mogą się powieść z powodu sesyjnych plików cookie (tj. Jeśli jesteś zalogowany) znajdujących się tylko w tej przeglądarce.
Joseph A.,
6
Aby rozwiązać problemy z poleceniem curl, możesz użyć curl -v„pełnego”. Spowoduje to wydrukowanie do standardowego błędu różnych informacji o połączeniu, żądaniu i odpowiedzi. W takim przypadku zobaczysz, że odpowiedź zawiera HTTP 302 Found(kod przekierowania) i Locationnagłówek z adresem URL, do którego chcesz przejść. Następnie możesz man curldowiedzieć się, jak powiedzieć, aby śledził przekierowania.
Nathan Long,

Odpowiedzi:

59

Jest przekierowanie na serwer www-strony pod następującym adresem URL: http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg. Ponieważ jest to CDN, dokładne zachowanie (czy zostaniesz przekierowany czy nie) może zależeć od twojej lokalizacji.

curldomyślnie nie śledzi przekierowań. Aby to zrobić, dodaj -Largument:

curl -L -O https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.16-osx10.11-x86_64.dmg
techraf
źródło
6
Przekierowanie HTTPS na HTTP? To okropne i nie dziwię się, że Curl pozostawia to w spokoju ...
Toby Speight
A jeśli to nie rozwiąże? Może ma to coś wspólnego z .asp?
matematyk
4

Jeśli przeglądarka jest w stanie pobrać plik, możesz sprawdzić, co robi przeglądarka. W Google Chrome możesz użyć następujących opcji, aby zobaczyć, co się dzieje.

1) [Widok> Deweloper> Narzędzia programistyczne> Karta Sieć> karta Nagłówki]

2) Kliknij link pobierania.

3) Link do pliku pojawi się na karcie narzędzi programistycznych.

4) Kliknij plik prawym przyciskiem myszy i wybierz Kopiuj> Kopiuj jako cURL.

Teraz masz link curl, który zadziała. Prawdopodobnie będzie miał nadmiar parametrów, które można odciąć.

Więcej informacji: https://lornajane.net/posts/2013/chrome-feature-copy-as-curl

klatka szybowa
źródło
0

Zamienię jeden z komentarzy do tego postu na odpowiedź.

Istnieje wiele łączy HTTP / HTTPS, które wymagają pewnych nagłówków, aby działać. Będzie to skutkować działającą odpowiedzią przeglądarki internetowej, ale nie działającą odpowiedzią na żądanie WWW zaplecza, takie jak curl.

Właśnie natrafiłem na stronę, która wymagała wszystkich następujących nagłówków. Brak ich określenia spowodował przekroczenie limitu czasu.

  httpget.setHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36");
  httpget.setHeader("Upgrade-Insecure-Requests", "1");
  httpget.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
  httpget.setHeader("Accept-Encoding", "gzip, deflate, br");
  httpget.setHeader("Accept-Language", "en-US,en;q=0.9");
  httpget.setHeader("Connection", "keep-alive");
  httpget.setHeader("Host", "www.thehost.com");
Nicholas DiPiazza
źródło