简体   繁体   中英

Scraping issues on a specific website

This is my first question on stack overflow so bear with me, please.

I am trying to download automatically (ie scrape) the text of some Italian laws from the website: http://www.normattiva.it/

I am using this code below (and similar permutations):

import requests, sys

debug = {'verbose': sys.stderr}
user_agent = {'User-agent': 'Mozilla/5.0', 'Connection':'keep-alive'}

url = 'http://www.normattiva.it/atto/caricaArticolo?art.progressivo=0&art.idArticolo=1&art.versione=1&art.codiceRedazionale=047U0001&art.dataPubblicazioneGazzetta=1947-12-27&atto.tipoProvvedimento=COSTITUZIONE&art.idGruppo=1&art.idSottoArticolo1=10&art.idSottoArticolo=1&art.flagTipoArticolo=0#art'

r = requests.session()
s = r.get(url, headers=user_agent)
#print(s.text)
print(s.url)
print(s.headers)
print(s.request.headers)

As you can see I am trying to load the " caricaArticolo " query.

However, the output is a page saying that my search is invalid ( "session is not valid or expired" )

It seems that the page recognizes that I am not using a browser and loads a "breakout" javascript function.

<body onload="javascript:breakout();">

I tried to use "browser" simulator python scripts such as selenium and robobrowser but the result is the same.

Is there anyone who is willing to spend 10 minutes looking at the page output and give help?

Once you click any link on the page with dev tools open, under the doc tab under Network:

在此处输入图片说明

You can see three links, the first is what we click on, the second returns the html that allows you to jump to a specific Article and the last contains the article text.

In the source returned from the firstlink, you can see two iframe tags:

<div id="alberoTesto">
        <iframe  
            src="/atto/caricaAlberoArticoli?atto.dataPubblicazioneGazzetta=2016-08-31&atto.codiceRedazionale=16G00182&atto.tipoProvvedimento=DECRETO LEGISLATIVO" 
            name="leftFrame" scrolling="auto" id="leftFrame" title="leftFrame" height="100%" style="width: 285px; float:left;" frameborder="0">
        </iframe>

        <iframe 
            src="/atto/caricaArticoloDefault?atto.dataPubblicazioneGazzetta=2016-08-31&atto.codiceRedazionale=16G00182&atto.tipoProvvedimento=DECRETO LEGISLATIVO" 
            name="mainFrame" id="mainFrame" title="mainFrame" height="100%" style="width: 800px; float:left;" scrolling="auto" frameborder="0">
        </iframe>

The first is for the Article, the latter with /caricaArticoloDefault and the id mainFrame is what we want.

You need to use the cookies from the initial requests so you can do it with the Session object and by parsing the pages using bs4 :

import requests, sys
import os
from urlparse import urljoin
import io
user_agent = {'User-agent': 'Mozilla/5.0', 'Connection': 'keep-alive'}

url = 'http://www.normattiva.it/atto/caricaArticolo?art.progressivo=0&art.idArticolo=1&art.versione=1&art.codiceRedazionale=047U0001&art.dataPubblicazioneGazzetta=1947-12-27&atto.tipoProvvedimento=COSTITUZIONE&art.idGruppo=1&art.idSottoArticolo1=10&art.idSottoArticolo=1&art.flagTipoArticolo=0#art'

with requests.session() as s:
    s.headers.update(user_agent)
    r = s.get("http://www.normattiva.it/")
    soup = BeautifulSoup(r.content, "lxml")
    # get all the links from the initial page
    for a in soup.select("div.testo p a[href^=http]"):
        soup = BeautifulSoup(s.get(a["href"]).content)
        # The link to the text is in a iframe tag retuened from the previous get.

        text_src_link = soup.select_one("#mainFrame")["src"]

        # Pick something to make the names unique
        with io.open(os.path.basename(text_src_link), "w", encoding="utf-8") as f:
            # The text is in pre tag that is in the  div with the pre class
            text = BeautifulSoup(s.get(urljoin("http://www.normattiva.it", text_src_link)).content, "html.parser")\
                .select_one("div.wrapper_pre pre").text
            f.write(text)

A snippet of the first text file:

                IL PRESIDENTE DELLA REPUBBLICA
  Visti  gli  articoli 76, 87 e 117, secondo comma, lettera d), della
Costituzione;
  Vistala   legge  28  novembre  2005,  n.  246  e,  in  particolare,
l'articolo 14:
   comma  14, cosi' come sostituito dall'articolo 4, comma 1, lettera
a),  della  legge  18  giugno  2009,  n.  69,  con  il quale e' stata
conferita  al  Governo la delega ad adottare, con le modalita' di cui
all'articolo 20 della legge 15 marzo 1997, n. 59, decreti legislativi
che  individuano  le  disposizioni  legislative  statali,  pubblicate
anteriormente   al   1°   gennaio   1970,  anche  se  modificate  con
provvedimenti  successivi,  delle  quali si ritiene indispensabile la
permanenza  in vigore, secondo i principi e criteri direttivi fissati
nello stesso comma 14, dalla lettera a) alla lettera h);
   comma  15,  con cui si stabilisce che i decreti legislativi di cui
al  citato  comma 14, provvedono, altresi', alla semplificazione o al
riassetto  della materia che ne e' oggetto, nel rispetto dei principi
e criteri direttivi di cui all'articolo 20 della legge 15 marzo 1997,
n.  59,  anche  al  fine  di armonizzare le disposizioni mantenute in
vigore con quelle pubblicate successivamente alla data del 1° gennaio
1970;
   comma 22, con cui si stabiliscono i termini per l'acquisizione del
prescritto  parere  da  parte  della  Commissione parlamentare per la
semplificazione;
  Visto  il  decreto  legislativo  30  luglio  1999,  n. 300, recante
riforma  dell'organizzazione  del  Governo,  a norma dell'articolo 11
della  legge  15 marzo 1997, n. 59 e, in particolare, gli articoli da
20 a 22;

wonderful, wonderful, wonderful Padraic. It works. Just had to edits slightly to clear imports but it's works wonderfully. Thanks very much. I am just discovering python's potential and you have made my journey much easier with this specific task. I would have not solved it alone.

import requests, sys
import os
from urllib.parse import urljoin
from bs4 import BeautifulSoup
import io
user_agent = {'User-agent': 'Mozilla/5.0', 'Connection': 'keep-alive'}

url = 'http://www.normattiva.it/atto/caricaArticolo?art.progressivo=0&art.idArticolo=1&art.versione=1&art.codiceRedazionale=047U0001&art.dataPubblicazioneGazzetta=1947-12-27&atto.tipoProvvedimento=COSTITUZIONE&art.idGruppo=1&art.idSottoArticolo1=10&art.idSottoArticolo=1&art.flagTipoArticolo=0#art'

with requests.session() as s:
    s.headers.update(user_agent)
    r = s.get("http://www.normattiva.it/")
    soup = BeautifulSoup(r.content, "lxml")
    # get all the links from the initial page
    for a in soup.select("div.testo p a[href^=http]"):
        soup = BeautifulSoup(s.get(a["href"]).content)
        # The link to the text is in a iframe tag retuened from the previous get.

        text_src_link = soup.select_one("#mainFrame")["src"]

        # Pick something to make the names unique
        with io.open(os.path.basename(text_src_link), "w", encoding="utf-8") as f:
            # The text is in pre tag that is in the  div with the pre class
            text = BeautifulSoup(s.get(urljoin("http://www.normattiva.it", text_src_link)).content, "html.parser")\
                .select_one("div.wrapper_pre pre").text
            f.write(text)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM