FLICKR - wyciągnięcie pierwszych 20 fotek

0

Próbuje wyciągnąć linki ze strony flickr.com ze zdjęciami, oto mój kod:

# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
from urllib.request import urlopen, Request
import re

url="https://www.flickr.com/search/?text=fuji%20x-t10%20XF18-55"
images = []

def flickr():
    #req = Request(url, data=None, headers={''})
    page = urlopen(url)
    soup = BeautifulSoup(page.read(), 'html.parser')
    howmany = soup.find('a', {'class' : 'view-more-link'})
    print('Znaleziono: ' + howmany.string[9:] + ' zdjęć.')	
    print(len(howmany))
    photo_results = soup.find_all('div', {'class' : 'photo-list-photo-interaction'})
    print(len(photo_results))
    for photo in photo_results:
        photo_link = photo.find('a', {'class' : 'overlay'})
        print(photo_link)

	
flickr()

Z różnych DIVów i bezpośrednio z linków <A> próbowałem wyciągnąć dane i nic. Zawsze dostaje 0 rezultatów (print(len(photo_results)) ). Już nie wiem o chodzi.

User-agent jest (chwilowo) ominięty, ale stronę ściąga, bo przynajmniej wyświetla liczbę zdjęć na dane zapytanie.

Chciałem wyciągnąć linki do zdjęć high-res i później je ściągnać na dysk, ale coś mi nie wychodzi.

Help!

1

A może elementy są doczytywane za pomocą JavaScript.
Spróbuj może zapisać stronę do pliku lub pobrać za pomocą np. wget i przejrzeć co tam masz.

Jeśli elementy są doczytywane przez JavaScript
to trzeba zobaczyć w przeglądarce jakie są wywołania AJAX
i je wykorzystać w skrypcie Pythona.

Albo zastosować w Pythonie narzędzia typu Selenium.

0

Strona flickr.com jest dostępna dla wszystkich ;) Nazwy klas, ID, itp. brałem z FireBug-a. Więc tu błędu nie popełniłem, próbowałem z różnymi znacznikami.

Co do AJAX-a, tak strona jest "dogrywana", ale mnie satysfakcjonuje pierwsze 20 fotek, a na starcie masz więcej (jeśli dane zapytanie jest odpowiednie).

Selenium to spora kobyła, a ja chiałem mały skrypcik.

Furas (albo ktoś inny), jakbyś miał jakiś pomysł dlaczego to "nie gra" to daj znać.

Stawiam pierwsze kroki z BS4, ale z allegro, gumtree czy sprzedajemy.pl nie miałem większych problemów. Jak widzisz kod wyświetla prawidłową liczbę zdjęć, dalej coś już jest nie tak.

Jest oczywiście inny sposób -oficjalne API ;) (jest kilka wrapperów dla Pythona), ale powiem szczerze, że wolałbym to zrobić "tradycyjnie".

0

A jeszcze jedno:

link url można (powinno się) skrócić do:

url="https://www.flickr.com/search/?text=fuji%20x-t10"

Będzie więcej wyników.

Mleczarz

0

Jeśli chodzi o pętle for

  
  for photo in photo_results:
        photo_link = photo.find('a', {'class' : 'overlay'})
        print(photo_link)

to próbowałem różnych rzeczy, np. photo_link['href'], itd. ale problem leży gdzie indziej -> find_all po prostu nie znajduje tego co powinno znaleźć.

1

Akurat używam requests i lxml ale takie coś

import requests
import lxml, lxml.html

r = requests.get('https://www.flickr.com/search/?text=fuji%20x-t10')

html = lxml.html.fromstring(r.text)

for i, x in enumerate(html.cssselect(".view.photo-list-photo-view.requiredToShowOnServer.awake")):
        style = x.get('style')
        print i, style[style.find("url"):]

Daje mi wynik

''0 url(//c2.staticflickr.com/6/5325/17863006508_1d496567af_n.jpg)
1 url(//c1.staticflickr.com/1/469/19446469261_086d5ac0b0_m.jpg)
2 url(//c1.staticflickr.com/1/447/18821555713_ea18f71ec6_m.jpg)
3 url(//c1.staticflickr.com/1/688/21649649363_11769682f2_n.jpg)
4 url(//c1.staticflickr.com/1/775/22208614681_5a4d1024e2_n.jpg)
5 url(//c2.staticflickr.com/6/5779/21145794474_19be3be843_m.jpg)
6 url(//c1.staticflickr.com/1/578/21852395410_da186f447f_m.jpg)
7 url(//c1.staticflickr.com/1/749/20934086849_d34e5866cc_m.jpg)
8 url(//c1.staticflickr.com/1/671/22082932328_e40aa73112_n.jpg)
9 url(//c2.staticflickr.com/6/5828/22040572615_57a98e1155_m.jpg)
10 url(//c1.staticflickr.com/1/588/22115143336_80bc2e4fa6_m.jpg)
11 url(//c1.staticflickr.com/1/509/19116901570_2de560a7e1_n.jpg)
12 url(//c1.staticflickr.com/1/498/19976471639_514188f886_n.jpg)
13 url(//c1.staticflickr.com/1/266/20039989196_0c6a948d3b_n.jpg)
14 url(//c2.staticflickr.com/6/5775/22270694515_b0bc29553c_n.jpg)
15 url(//c1.staticflickr.com/1/498/20020999948_d4df7ed454_n.jpg)
16 url(//c1.staticflickr.com/1/441/19637314404_4858a9c00e_n.jpg)
17 url(//c1.staticflickr.com/1/742/20120794493_e17562d9a6_m.jpg)
18 url(//c1.staticflickr.com/1/408/19662314983_a4e1cd6308_n.jpg)
19 url(//c2.staticflickr.com/6/5818/21432323871_d686cdd5e5_m.jpg)
20 url(//c2.staticflickr.com/6/5688/20868549592_9bcd4c2971_n.jpg)
21 url(//c1.staticflickr.com/1/616/21012564040_49bab8a197_n.jpg)
22 url(//c1.staticflickr.com/1/264/19276805734_1aa5edd85d_n.jpg)''


Za to pobranie a.overlay nic nie daje.
Może być tak, że ten element jest tworzony przez JavaScript
a Firebug pokazuje aktualny stan czyli zmodyfilowany przez skrypt
a nie to co było pierwotnie w pliku .html

import requests
import lxml, lxml.html

r = requests.get('https://www.flickr.com/search/?text=fuji%20x-t10')

html = lxml.html.fromstring(r.text)

for i, x in enumerate(html.cssselect("a.overlay")):
        print i, x.get('href')
0

Piękne dzięki!

Krótko, zwięźle, super! Nie używałem dotąd LXML, ale się zapoznam z podstawami.

Wydaje mi się, że masz rację, z tym JS / FireBug, itd.

Jeszcze nie odpaliłem Twojego przykładu, ale skoro u Ciebie działa, to jest OK.

Jeszcze raz- wielkie dzięki!.

Mleczarz

1 użytkowników online, w tym zalogowanych: 0, gości: 1