-2

Why does my code only finds 5 articles instead all of all 30 in the page?

Here is my code:

    import requests
    from bs4 import BeautifulSoup
    import pandas as pd
    
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'}
    
    url = 'https://www.15min.lt/tema/svietimas-24297'
    r = requests.get(url, headers=headers)
    soup = BeautifulSoup(r.text, 'html.parser')
    
    antrastes = soup.find_all('h3', {'class': 'vl-title'})
    
    print(antrastes)
baduker
  • 19,152
  • 9
  • 33
  • 56
  • 3
    You need to scroll the page to get all the contents. this [question](https://stackoverflow.com/questions/21006940/how-to-load-all-entries-in-an-infinite-scroll-at-once-to-parse-the-html-in-pytho) can help you using Selenium – A D Mar 09 '22 at 15:00
  • this page use JavaScript to add elements but `requests`/`BeautifulSoup` can't use `JavaScript`. It may need to use [Selenium](https://selenium-python.readthedocs.io/) to control real web browser which can run `JavaScript`. And it may need also some JavaScript code to scroll page. Evntually you can check in DevTools in Firefox/Chrome if JavaScritp load data from some URL and you can try to use this URL with `requests`. It may need to use Session to get cookies and headers from first GET, – furas Mar 09 '22 at 19:06

1 Answers1

0

Page uses JavaScript to add items but requests/BeautifulSoup can't run JavaScript.

It may need to use Selenium to control real web browser which can run JavaScript.
And it may also need some JavaScript code to scroll page.

Eventually you can check in DevTools in Firefox/Chrome if JavaScript loads data from some URL and you can try to use this URL with requests. It may need to use Session to get cookies and headers from first GET.


This code uses URL which I found in DevTools (tab: Network, filter: XHR).

It needs to set different offset (date time) in url to get different rows - url.format(offset)

If you use current datetime then you don't even need to read main page.

It needs header 'X-Requested-With': 'XMLHttpRequest' to work.

It sends JSON data with keys rows (with HTML) and offset (with datetime for next rows).
And I use this offset to get next rows. I run this in loop to get more rows.

import urllib.parse
import requests
from bs4 import BeautifulSoup
import datetime

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36',
    'X-Requested-With': 'XMLHttpRequest',
}

url = 'https://www.15min.lt/tags/ajax/list/svietimas-24297?tag=24297&type=&offset={}&last_row=2&iq=L&force_wide=true&cachable=1&layout%5Bw%5D%5B%5D=half_wide&layout%5Bw%5D%5B%5D=third_wide&layout%5Bf%5D%5B%5D=half_wide&layout%5Bf%5D%5B%5D=third_wide&cosite=default'

offset = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

for _ in range(5):
    print('=====', offset, '=====')
    
    offset = urllib.parse.quote_plus(offset)
    
    response = requests.get(url.format(offset), headers=headers)
    
    data = response.json()
    
    soup = BeautifulSoup(data['rows'], 'html.parser')
    antrastes = soup.find_all('h3', {'class': 'vl-title'})
    
    for item in antrastes:
        print(item.text.strip())
        print('---')
    
    offset = data['offset']  # offset for next data

Result:

===== 2022-03-09 21:20:36 =====
Konkursas „Praeities stiprybė – dabarčiai“. Susipažinkite su finalininkų darbais ir išrinkite nugalėtojus
---
ŠMSM į ukrainiečių vaikų ugdymą žada įtraukti ir atvykstančius mokytojus
---
Didėjant būrelių Vilniuje finansavimui, tikimasi įtraukti ir ukrainiečių vaikus
---
Mylėti priešus – ne glostyti palei plauką
---
Atvira pamoka su prof. Alfredu Bumblausku: „Ką reikėtų žinoti apie Ukrainos istoriją?“
---
===== 2022-03-04 13:20:21 =====
Vilniečiams vaikams – didesnis neformaliojo švietimo krepšelis
---
Premjerė: sudėtingiausiose situacijoje mokslo ir mokslininkų svarba tik didėja
---
Prasideda priėmimas į sostinės mokyklas: ką svarbu žinoti?
---
Dešimtokai lietuvių kalbos ir matematikos pasiekimus gegužę tikrinsis nuotoliniu būdu
---
Vilniuje prasideda priėmimas į mokyklas
---
===== 2022-03-01 07:09:05 =====
Nuotolinė istorijos pamoka apie Ukrainą sulaukė 30 tūkst. peržiūrų
---
J.Šiugždinienė: po Ukrainos pergalės bendradarbiavimas su šia herojiška valstybe tik didės
---
Vilniaus savivaldybė svarsto įkurdinti moksleivius buvusiame „Ignitis“ pastate
---
Socialdemokratai ragina stabdyti švietimo įstaigų tinklo pertvarką
---
Pokyčiai mokyklinėje literatūros programoje: mažiau privalomų autorių, brandos egzaminas – iš kelių dalių
---
===== 2022-02-26 11:04:29 =====
Mokytojo Gyčio „pagalbos“ – žygis, puodas ir uodas
---
Nuo kovo 2-osios pradinukams klasėse nebereikės dėvėti kaukių
---
Dr. Austėja Landsbergienė: Matematikos nerimas – kas tai ir ar įmanoma išvengti?
---
Ukrainos palaikymui – visuotinė istorijos pamoka Lietuvos mokykloms
---
Mokinius kviečia didžiausias chemijos dalyko konkursas Lietuvoje
---
===== 2022-02-23 10:11:14 =====
Mokyklų tinklo stiprinimas savivaldybėse: klausimai ir atsakymai
---
Vaiko ir paauglio kelias į sėkmę, arba Kaip gauti Nobelio premiją
---
Geriausias ugdymas – žygis, laužas, puodas ir uodas
---
Vilija Targamadzė: Bendrojo ugdymo mokyklų reformatoriai, ar ir toliau sėsite kakofoniją?
---
Švietimo ministrė: tai, kad turime sujungtas 5–8 klases, yra kažkas baisaus
---
furas
  • 134,197
  • 12
  • 106
  • 148