Différences entre les versions de « Lea »
(→Q2) |
|||
(30 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 6 : | Ligne 6 : | ||
− | Je souhaite réaliser une base de données qui collecterait | + | Je souhaite réaliser une base de données qui collecterait les photographies numérisées de centres d'archive de la communauté lgbtqia+ et des personnes sexisées (Drouar, 2020) afin de leur donner plus de visibilité et nous permettre de lutter contre le processus de désindividuation. Je suis très intéressé par la notion de mémoire collective et la manière dont nous nous construisons à travers l'hypomnémata numérique, c'est-à-dire internet. Un hypomnémata est, selon Platon, un objet technique nous permettant de nous souvenir. Il est un support externe de mémoire. Selon Bernard Stiegler, dans la lignée de Gilbert Simondon, tout objet technique est pharmacologique dans le sens où il est le remède comme le poison. Je m'intéresse ainsi aux bienfaits que peut procurer le web 2.0 comme notamment la mise en commun et le partage de savoirs. |
Ligne 30 : | Ligne 30 : | ||
== Structure == | == Structure == | ||
+ | |||
+ | Diagramme de la structure de la base de données : | ||
+ | |||
+ | [[Fichier:Diagram_lea.jpg]] | ||
+ | |||
+ | |||
+ | == Programme == | ||
+ | |||
+ | Objectif : Elaboration du programme en python pour récolter les images et leurs caractéristiques (titre, date, source...etc). | ||
+ | |||
+ | 1-Tout d'abord, il a fallu que je repère les selecteurs css qui contiennent les informations qui me sont nécessaire. | ||
+ | |||
+ | page cible : https://www.digitaltransgenderarchive.net/catalog?f%5Bgenre_ssim%5D%5B%5D=Photographs | ||
+ | |||
+ | |||
+ | [[Fichier:Screen Shot 2021-01-19 at 16.53.29 copie.jpg]] | ||
+ | |||
+ | |||
+ | 2-Se connecter au site à partir de mechanize | ||
+ | |||
+ | 3-Insérer dans le code les selecteurs css qui m'intéresse, les récupérer, les encoder puis les convertir (nom de l'image, date...etc). Récupérer les url des images pour les télécharger. | ||
+ | |||
+ | 4-Printer les données | ||
+ | |||
+ | |||
+ | Les screenshots de mes premiers tests : | ||
+ | |||
+ | [[Fichier:Screen Shot 2021-01-19 at 18.41.27 copie.jpg]] | ||
+ | |||
+ | |||
+ | [[Fichier:Screen Shot 2021-01-19 at 18.44.20 copie.jpg]] | ||
+ | |||
+ | Résultat test de récupération d'url image : | ||
+ | |||
+ | [[Fichier:Screen Shot 2021-01-19 at 18.41.11 copie.jpg]] | ||
+ | |||
+ | |||
+ | Schéma de mon programme : | ||
+ | |||
+ | [[Fichier:Untitled Diagram2_Lea.png]] | ||
+ | |||
+ | == Notes == | ||
+ | |||
+ | C'était un peu difficile, j'ai l'impression que je commence à comprendre mais qu'il y a des erreurs dans mon travail. J'espère que mon avancée est suffisante pour ce premier quadri ! Bonne lecture :) | ||
+ | |||
+ | == Q2 // travail réalisé avec Mondher == | ||
+ | |||
+ | Travail réalisé en binôme avec [[Mondher]] à partir de ces journaux : | ||
+ | |||
+ | |||
+ | Belgique : | ||
+ | |||
+ | https://www.lesoir.be | ||
+ | https://www.lecho.be | ||
+ | https://www.lalibre.be | ||
+ | https://fr.metrotime.be | ||
+ | |||
+ | Suisse : | ||
+ | |||
+ | https://www.24heures.ch | ||
+ | https://www.lematin.ch | ||
+ | https://www.lenouvelliste.ch | ||
+ | https://www.tdg.ch | ||
+ | https://www.arcinfo.ch | ||
+ | https://www.heidi.news | ||
+ | https://www.lacote.ch | ||
+ | https://lecourrier.ch | ||
+ | https://www.letemps.ch | ||
+ | https://www.agefi.fr | ||
+ | https://www.lqj.ch | ||
+ | |||
+ | France : | ||
+ | |||
+ | https://www.lefigaro.fr | ||
+ | https://www.lemonde.fr | ||
+ | https://www.lesechos.fr | ||
+ | https://www.leparisien.fr | ||
+ | https://www.liberation.fr | ||
+ | https://www.la-croix.com | ||
+ | https://www.lequipe.fr | ||
+ | https://www.dhnet.be | ||
+ | |||
+ | Luxembourg : | ||
+ | |||
+ | https://www.lessentiel.lu/fr/luxembourg/ | ||
+ | https://lequotidien.lu | ||
+ | |||
+ | Monaco : | ||
+ | |||
+ | https://www.monacomatin.mc | ||
+ | |||
+ | == les selecteurs == | ||
+ | |||
+ | Nous avons cherché les sélecteurs qui nous intéressait pour les inclure dans le code. | ||
+ | |||
+ | Belgique : | ||
+ | |||
+ | https://www.lesoir.be | ||
+ | |||
+ | titre : h1 | ||
+ | date : time.pubdate.updated | ||
+ | |||
+ | |||
+ | https://www.lecho.be | ||
+ | |||
+ | titre : article h1 | ||
+ | date : time classe=“js-timeToday” datetime // span.js-timeToday-time | ||
+ | date modification : itemprop | ||
+ | |||
+ | https://www.lalibre.be | ||
+ | |||
+ | titre : article h1 | ||
+ | date : time datetime | ||
+ | date de modification : time datetime | ||
+ | |||
+ | https://fr.metrotime.be | ||
+ | |||
+ | titre : h1.entry-title | ||
+ | date : time.entry-date.updated.td-module-date | ||
+ | date de modififaction datetime | ||
+ | |||
+ | Suisse : | ||
+ | |||
+ | https://www.24heures.ch | ||
+ | |||
+ | titre : h1 Span ContentHead | ||
+ | date : article time | ||
+ | |||
+ | https://www.lematin.ch | ||
+ | |||
+ | titre : article h1 | ||
+ | date : article time | ||
+ | date de modification : article datetime | ||
+ | |||
+ | |||
+ | https://www.lenouvelliste.ch | ||
+ | |||
+ | titre : article h1 | ||
+ | date : article datetime | ||
+ | |||
+ | https://www.tdg.ch | ||
+ | |||
+ | titre : article h1, article h3, article h2 | ||
+ | date : article FullDateTime | ||
+ | |||
+ | https://www.arcinfo.ch | ||
+ | |||
+ | titre : article h3, article h1, article h2 | ||
+ | date : article datetime | ||
+ | |||
+ | |||
+ | https://www.heidi.news | ||
+ | |||
+ | titre: article h2, article h1, article h3 | ||
+ | date : article datetime | ||
+ | |||
+ | https://www.lacote.ch | ||
+ | |||
+ | titre : h1 | ||
+ | date : div class=“datetime” | ||
+ | |||
+ | |||
+ | https://lecourrier.ch | ||
+ | |||
+ | titre : h1 article titre | ||
+ | date : article metaDate | ||
+ | |||
+ | https://www.letemps.ch | ||
+ | |||
+ | titre : h1 | ||
+ | date publication : div class=“date” | ||
+ | date de modification : div class=“date” | ||
+ | |||
+ | http://www.agefi.fr | ||
+ | |||
+ | titre : h1 class=“node_title title title—xl” | ||
+ | date : span class=“node_date node_infos__item” | ||
+ | |||
+ | |||
+ | https://www.lqj.ch | ||
+ | |||
+ | titre : div class=“ekk-article-title” | ||
+ | date : span class=“date-display-single” | ||
+ | |||
+ | France : | ||
+ | |||
+ | https://www.lefigaro.fr | ||
+ | https://www.lemonde.fr | ||
+ | https://www.lesechos.fr | ||
+ | https://www.leparisien.fr | ||
+ | https://www.liberation.fr | ||
+ | date: div.font_xs.color_grey.font_tertiary | ||
+ | |||
+ | https://www.la-croix.com | ||
+ | https://www.lequipe.fr | ||
+ | https://www.dhnet.be | ||
+ | |||
+ | |||
+ | Luxembourg : | ||
+ | |||
+ | http://www.lessentiel.lu/fr/luxembourg/ | ||
+ | |||
+ | titre : h1, h2, h3 | ||
+ | date : p | ||
+ | |||
+ | https://lequotidien.lu | ||
+ | |||
+ | titre : h1, h2, h3 | ||
+ | date : p.post-meta (récupérer .text et pas .text_content() | ||
+ | |||
+ | Monaco : | ||
+ | |||
+ | https://www.monacomatin.mc | ||
+ | |||
+ | titre : h1, h2, h3 | ||
+ | date de création : span class=“separator” | ||
+ | date de publication : span class=“separator” | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | == Données == | ||
+ | |||
+ | un exemple de données que l'on a réussit à obtenir avec le terminal. Malheureusement comme le précise Mondher sur sa page, nous n'avons pas réussi à les récupérer dans phpmyadmin. Certains sélecteurs étaient également faux. Nous n'avons pas eu le temps de finir ce projet et de le peaufiner. | ||
+ | |||
+ | [[Fichier:terminal (dragged).jpeg]] | ||
+ | |||
+ | == CODE == | ||
+ | |||
+ | Réalisation d'un code pour récupérer des données et les insérer dans une base de données | ||
+ | |||
+ | <syntaxhighlight lang="python">import time | ||
+ | import mechanize | ||
+ | import lxml.html as lh | ||
+ | import cssselect | ||
+ | import ssl | ||
+ | import os | ||
+ | from urllib.parse import urlparse | ||
+ | import mysql.connector as mysql | ||
+ | |||
+ | def getSrcFromURL(url): | ||
+ | data = br.open(url) | ||
+ | |||
+ | rawdata = data.read() | ||
+ | unicode = rawdata.decode('utf-8', 'ignore') | ||
+ | src = lh.fromstring(unicode) | ||
+ | return src | ||
+ | |||
+ | def getResults(src, selecteurs): | ||
+ | results = [] | ||
+ | cssSelectSelecteurs = cssselect.parse(selecteurs) | ||
+ | for cssSelectSelecteur in cssSelectSelecteurs: | ||
+ | chemin_xpath = cssselect.HTMLTranslator().selector_to_xpath(cssSelectSelecteur, translate_pseudo_elements=True) | ||
+ | results = results + src.xpath(chemin_xpath) | ||
+ | |||
+ | return results | ||
+ | |||
+ | |||
+ | #initialisation de l'objet db, interface avec la base de données mysql | ||
+ | db = mysql.connect( | ||
+ | host = "localhost", | ||
+ | port = "8889", | ||
+ | user = "root", | ||
+ | passwd = "root", | ||
+ | database = "indice_popularité_termes" | ||
+ | ) | ||
+ | |||
+ | def getData(htmlElements, operation): | ||
+ | data = [] | ||
+ | for element in htmlElements: | ||
+ | if operation == 'get_href': | ||
+ | data.append(element.get('href')) | ||
+ | elif operation == 'get_content_date': | ||
+ | #2021-04-19T10:09:10+00:00 | ||
+ | #2021-04-19 10:09:10 | ||
+ | date = element.get('content') | ||
+ | date = date.replace('T', ' ') | ||
+ | date = date[0:19] | ||
+ | data.append(date) | ||
+ | elif operation == 'text_content': | ||
+ | data.append(element.text_content()) | ||
+ | elif operation == 'get_datetime': | ||
+ | data.append(element.get('datetime')) | ||
+ | |||
+ | return data | ||
+ | |||
+ | |||
+ | selecteurs = [ | ||
+ | # { | ||
+ | # 'url':'https://www.lenouvelliste.ch', | ||
+ | # 'source_id':, | ||
+ | # 'selecteur_links':{'name':'article_link', 'selecteur':'h1 a, h3 a', 'operation':'get_href'}, | ||
+ | # 'selecteurs_article':[ | ||
+ | # {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'}, | ||
+ | # {'name': 'date_pub', 'selecteur': 'article datetime', 'operation':'text_content'}, | ||
+ | # ] | ||
+ | |||
+ | # }, | ||
+ | # { | ||
+ | # 'url':'https://www.arcinfo.ch', | ||
+ | # 'source_id':9, | ||
+ | # 'selecteur_links':{'name':'article_link', 'selecteur':'h1 a, h3 a', 'operation':'get_href'}, | ||
+ | # 'selecteurs_article':[ | ||
+ | # {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'}, | ||
+ | # {'name': 'date_pub', 'selecteur': 'small', 'operation':'text_content'}, | ||
+ | # ] | ||
+ | |||
+ | # }, | ||
+ | # { | ||
+ | # 'url':'https://www.heidi.news', | ||
+ | # 'source_id':10, | ||
+ | # 'selecteur_links':{'name':'article_link', 'selecteur':'h3 a, h2 a', 'operation':'get_href'}, | ||
+ | # 'selecteurs_article':[ | ||
+ | # {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'}, | ||
+ | # {'name': 'date_pub', 'selecteur': 'article datetime', 'operation':'text_content'}, | ||
+ | # ] | ||
+ | |||
+ | # }, | ||
+ | { | ||
+ | 'url':'https://www.lacote.ch', | ||
+ | 'source_id':11, | ||
+ | 'selecteur_links':{'name':'article_link', 'selecteur':'h3 a, h2 a', 'operation':'get_href'}, | ||
+ | 'selecteurs_article':[ | ||
+ | {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'}, | ||
+ | {'name': 'date_pub', 'selecteur': 'small', 'operation':'text_content'}, | ||
+ | ] | ||
+ | |||
+ | }, | ||
+ | # { | ||
+ | # 'url':'https://lecourrier.ch', | ||
+ | # 'source_id':12, | ||
+ | # 'selecteur_links':{'name':'article_link', 'selecteur':'a.c-Card-permalink', 'operation':'get_href'}, | ||
+ | # 'selecteurs_article':[ | ||
+ | # {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'}, | ||
+ | # {'name': 'date_pub', 'selecteur': 'article metaDate', 'operation':'text_content'}, | ||
+ | # ] | ||
+ | |||
+ | # }, | ||
+ | # { | ||
+ | # 'url':'https://lemonde.fr', | ||
+ | # 'source_id':1, | ||
+ | # 'selecteur_links':{'name':'article_link', 'selecteur':'div.article a','operation':'get_href'}, | ||
+ | # 'selecteurs_article':[ | ||
+ | # {'name': 'titre', 'selecteur': 'h1.article__title', 'operation':'text_content'}, | ||
+ | # {'name': 'date_pub', 'selecteur': 'meta[property="og:article:published_time"]', 'operation':'get_content_date'}, | ||
+ | # ] | ||
+ | |||
+ | # }, | ||
+ | |||
+ | ] | ||
+ | |||
+ | #initialisation d'un objet "navigateur" avec la librairie mechanize | ||
+ | br = mechanize.Browser() | ||
+ | |||
+ | br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] | ||
+ | |||
+ | br.set_handle_robots(False) | ||
+ | #fin de la configuration de mechanize | ||
+ | |||
+ | try: | ||
+ | _create_unverified_https_context = ssl._create_unverified_context | ||
+ | except AttributeError: | ||
+ | # Legacy Python that doesn't verify HTTPS certificates by default | ||
+ | pass | ||
+ | else: | ||
+ | # Handle target environment that doesn't support HTTPS verification | ||
+ | ssl._create_default_https_context = _create_unverified_https_context | ||
+ | |||
+ | #0: pour chaque source dans le tableau sélecteurs | ||
+ | for source in selecteurs: | ||
+ | #0:récupérer l'id de la source dans la base de données | ||
+ | sourceId = source['source_id'] | ||
+ | #1: récupérer la première page de la source | ||
+ | premierePage = getSrcFromURL(source['url']) | ||
+ | #2: appliquer le sélecteur contenu dans 'selecteur_links' | ||
+ | liensArticles = getResults(premierePage, source['selecteur_links']['selecteur']) | ||
+ | #3: appliquer l'opération sur chaque élément récupéré -> url articles | ||
+ | urlsArticles = getData(liensArticles, source['selecteur_links']['operation']) | ||
+ | #4: pour chaque url article: | ||
+ | for urlArticle in urlsArticles: | ||
+ | #5: checker si l'url de l'article se trouve déjà dans la table article de la db. si il y est, skipper le reste des opérations | ||
+ | query = "SELECT * FROM article WHERE url='"+urlArticle+"'" | ||
+ | alreadyInDB = False | ||
+ | with db.cursor() as cursor: | ||
+ | cursor.execute(query) | ||
+ | result = cursor.fetchall() | ||
+ | if len(result) > 0: | ||
+ | alreadyInDB = True | ||
+ | |||
+ | if(alreadyInDB == True): | ||
+ | continue | ||
+ | |||
+ | #5bis: récupérer la source de la page désignée par l'url | ||
+ | # print(urlArticle) | ||
+ | sourceUrl = getSrcFromURL(urlArticle) | ||
+ | print(sourceUrl) | ||
+ | print(urlArticle) | ||
+ | # print(sourceUrl) | ||
+ | # #6: déclarer un tableau vide qui contiendra les éléments à insérer dans la db -> dataArticle | ||
+ | dataArticle = [] | ||
+ | # #7: pour chaque sélecteur contenu dans "selecteurs_article": | ||
+ | for selecteur_article in source['selecteurs_article']: | ||
+ | # #8: appliquer le sélecteur article sur la source de la page | ||
+ | applySelector = getResults(sourceUrl, selecteur_article['selecteur']) | ||
+ | # print(applySelector) | ||
+ | # #9: appliquer l'opération sur l'élément récupéré -> donnée | ||
+ | operateelement = getData(applySelector, selecteur_article['operation']) | ||
+ | #10: ajouter la donnée au tableau dataArticle | ||
+ | dataArticle.append(operateelement) | ||
+ | print(dataArticle) | ||
+ | |||
+ | if(len(dataArticle[0]) == 0): | ||
+ | continue | ||
+ | |||
+ | #[['Les Etats-Unis et la Chine «\xa0s’engagent à coopérer\xa0» sur la crise climatique'], ['2021-04-18 02:33:09']] | ||
+ | # #11: insérer le tableau dans la base de données | ||
+ | query = "INSERT INTO article (titre, date_crea, url, source_id) VALUES ('"+dataArticle[0][0]+"', '"+dataArticle[1][0]+"', '"+urlArticle+"', '"+str(sourceId)+"')" | ||
+ | print(query) | ||
+ | # query = "INSERT INTO article (titre, date_crea, source_id) VALUES ('%s', '%s', 1)" % (dataArticle[0], dataArticle[1]) | ||
+ | |||
+ | cursor = db.cursor() | ||
+ | cursor.execute(query) | ||
+ | db.commit() | ||
+ | </syntaxhighlight> | ||
+ | <br> | ||
+ | |||
+ | == La base de données == | ||
+ | |||
+ | [[Fichier:1codeleamondher.jpeg]] | ||
+ | |||
+ | [[Fichier:2codeleamondher.jpeg]] |
Version actuelle datée du 25 avril 2021 à 20:38
Projet
Je souhaite réaliser une base de données qui collecterait les photographies numérisées de centres d'archive de la communauté lgbtqia+ et des personnes sexisées (Drouar, 2020) afin de leur donner plus de visibilité et nous permettre de lutter contre le processus de désindividuation. Je suis très intéressé par la notion de mémoire collective et la manière dont nous nous construisons à travers l'hypomnémata numérique, c'est-à-dire internet. Un hypomnémata est, selon Platon, un objet technique nous permettant de nous souvenir. Il est un support externe de mémoire. Selon Bernard Stiegler, dans la lignée de Gilbert Simondon, tout objet technique est pharmacologique dans le sens où il est le remède comme le poison. Je m'intéresse ainsi aux bienfaits que peut procurer le web 2.0 comme notamment la mise en commun et le partage de savoirs.
Sources
Pour ce faire je souhaite puiser des images à travers ces différents sites :
https://www.digitaltransgenderarchive.net
http://dcmny.org/islandora/search/?type=edismax&cp=lesbianherstory%3Acollection
https://antrepeaux.net/ressources/
https://www.memoire-sexualites.org/category/marseille/
https://archiveslgbtqi.fr/organisation-du-collectif/
https://www.archivesdufeminisme.fr/ressources/sources-historiques/
http://bafe.fr/base-de-ressources/
Structure
Diagramme de la structure de la base de données :
Programme
Objectif : Elaboration du programme en python pour récolter les images et leurs caractéristiques (titre, date, source...etc).
1-Tout d'abord, il a fallu que je repère les selecteurs css qui contiennent les informations qui me sont nécessaire.
page cible : https://www.digitaltransgenderarchive.net/catalog?f%5Bgenre_ssim%5D%5B%5D=Photographs
2-Se connecter au site à partir de mechanize
3-Insérer dans le code les selecteurs css qui m'intéresse, les récupérer, les encoder puis les convertir (nom de l'image, date...etc). Récupérer les url des images pour les télécharger.
4-Printer les données
Les screenshots de mes premiers tests :
Résultat test de récupération d'url image :
Schéma de mon programme :
Notes
C'était un peu difficile, j'ai l'impression que je commence à comprendre mais qu'il y a des erreurs dans mon travail. J'espère que mon avancée est suffisante pour ce premier quadri ! Bonne lecture :)
Q2 // travail réalisé avec Mondher
Travail réalisé en binôme avec Mondher à partir de ces journaux :
Belgique :
https://www.lesoir.be https://www.lecho.be https://www.lalibre.be https://fr.metrotime.be
Suisse :
https://www.24heures.ch https://www.lematin.ch https://www.lenouvelliste.ch https://www.tdg.ch https://www.arcinfo.ch https://www.heidi.news https://www.lacote.ch https://lecourrier.ch https://www.letemps.ch https://www.agefi.fr https://www.lqj.ch
France :
https://www.lefigaro.fr https://www.lemonde.fr https://www.lesechos.fr https://www.leparisien.fr https://www.liberation.fr https://www.la-croix.com https://www.lequipe.fr https://www.dhnet.be
Luxembourg :
https://www.lessentiel.lu/fr/luxembourg/ https://lequotidien.lu
Monaco :
les selecteurs
Nous avons cherché les sélecteurs qui nous intéressait pour les inclure dans le code.
Belgique :
titre : h1 date : time.pubdate.updated
titre : article h1 date : time classe=“js-timeToday” datetime // span.js-timeToday-time date modification : itemprop
titre : article h1 date : time datetime date de modification : time datetime
titre : h1.entry-title date : time.entry-date.updated.td-module-date date de modififaction datetime
Suisse :
titre : h1 Span ContentHead date : article time
titre : article h1 date : article time date de modification : article datetime
titre : article h1 date : article datetime
titre : article h1, article h3, article h2 date : article FullDateTime
titre : article h3, article h1, article h2 date : article datetime
titre: article h2, article h1, article h3 date : article datetime
titre : h1 date : div class=“datetime”
titre : h1 article titre date : article metaDate
titre : h1 date publication : div class=“date” date de modification : div class=“date”
titre : h1 class=“node_title title title—xl” date : span class=“node_date node_infos__item”
titre : div class=“ekk-article-title” date : span class=“date-display-single”
France :
https://www.lefigaro.fr https://www.lemonde.fr https://www.lesechos.fr https://www.leparisien.fr https://www.liberation.fr date: div.font_xs.color_grey.font_tertiary
https://www.la-croix.com https://www.lequipe.fr https://www.dhnet.be
Luxembourg :
http://www.lessentiel.lu/fr/luxembourg/
titre : h1, h2, h3 date : p
titre : h1, h2, h3 date : p.post-meta (récupérer .text et pas .text_content()
Monaco :
titre : h1, h2, h3 date de création : span class=“separator” date de publication : span class=“separator”
Données
un exemple de données que l'on a réussit à obtenir avec le terminal. Malheureusement comme le précise Mondher sur sa page, nous n'avons pas réussi à les récupérer dans phpmyadmin. Certains sélecteurs étaient également faux. Nous n'avons pas eu le temps de finir ce projet et de le peaufiner.
CODE
Réalisation d'un code pour récupérer des données et les insérer dans une base de données
import time
import mechanize
import lxml.html as lh
import cssselect
import ssl
import os
from urllib.parse import urlparse
import mysql.connector as mysql
def getSrcFromURL(url):
data = br.open(url)
rawdata = data.read()
unicode = rawdata.decode('utf-8', 'ignore')
src = lh.fromstring(unicode)
return src
def getResults(src, selecteurs):
results = []
cssSelectSelecteurs = cssselect.parse(selecteurs)
for cssSelectSelecteur in cssSelectSelecteurs:
chemin_xpath = cssselect.HTMLTranslator().selector_to_xpath(cssSelectSelecteur, translate_pseudo_elements=True)
results = results + src.xpath(chemin_xpath)
return results
#initialisation de l'objet db, interface avec la base de données mysql
db = mysql.connect(
host = "localhost",
port = "8889",
user = "root",
passwd = "root",
database = "indice_popularité_termes"
)
def getData(htmlElements, operation):
data = []
for element in htmlElements:
if operation == 'get_href':
data.append(element.get('href'))
elif operation == 'get_content_date':
#2021-04-19T10:09:10+00:00
#2021-04-19 10:09:10
date = element.get('content')
date = date.replace('T', ' ')
date = date[0:19]
data.append(date)
elif operation == 'text_content':
data.append(element.text_content())
elif operation == 'get_datetime':
data.append(element.get('datetime'))
return data
selecteurs = [
# {
# 'url':'https://www.lenouvelliste.ch',
# 'source_id':,
# 'selecteur_links':{'name':'article_link', 'selecteur':'h1 a, h3 a', 'operation':'get_href'},
# 'selecteurs_article':[
# {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'},
# {'name': 'date_pub', 'selecteur': 'article datetime', 'operation':'text_content'},
# ]
# },
# {
# 'url':'https://www.arcinfo.ch',
# 'source_id':9,
# 'selecteur_links':{'name':'article_link', 'selecteur':'h1 a, h3 a', 'operation':'get_href'},
# 'selecteurs_article':[
# {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'},
# {'name': 'date_pub', 'selecteur': 'small', 'operation':'text_content'},
# ]
# },
# {
# 'url':'https://www.heidi.news',
# 'source_id':10,
# 'selecteur_links':{'name':'article_link', 'selecteur':'h3 a, h2 a', 'operation':'get_href'},
# 'selecteurs_article':[
# {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'},
# {'name': 'date_pub', 'selecteur': 'article datetime', 'operation':'text_content'},
# ]
# },
{
'url':'https://www.lacote.ch',
'source_id':11,
'selecteur_links':{'name':'article_link', 'selecteur':'h3 a, h2 a', 'operation':'get_href'},
'selecteurs_article':[
{'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'},
{'name': 'date_pub', 'selecteur': 'small', 'operation':'text_content'},
]
},
# {
# 'url':'https://lecourrier.ch',
# 'source_id':12,
# 'selecteur_links':{'name':'article_link', 'selecteur':'a.c-Card-permalink', 'operation':'get_href'},
# 'selecteurs_article':[
# {'name': 'titre', 'selecteur': 'article h1', 'operation':'text_content'},
# {'name': 'date_pub', 'selecteur': 'article metaDate', 'operation':'text_content'},
# ]
# },
# {
# 'url':'https://lemonde.fr',
# 'source_id':1,
# 'selecteur_links':{'name':'article_link', 'selecteur':'div.article a','operation':'get_href'},
# 'selecteurs_article':[
# {'name': 'titre', 'selecteur': 'h1.article__title', 'operation':'text_content'},
# {'name': 'date_pub', 'selecteur': 'meta[property="og:article:published_time"]', 'operation':'get_content_date'},
# ]
# },
]
#initialisation d'un objet "navigateur" avec la librairie mechanize
br = mechanize.Browser()
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]
br.set_handle_robots(False)
#fin de la configuration de mechanize
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
#0: pour chaque source dans le tableau sélecteurs
for source in selecteurs:
#0:récupérer l'id de la source dans la base de données
sourceId = source['source_id']
#1: récupérer la première page de la source
premierePage = getSrcFromURL(source['url'])
#2: appliquer le sélecteur contenu dans 'selecteur_links'
liensArticles = getResults(premierePage, source['selecteur_links']['selecteur'])
#3: appliquer l'opération sur chaque élément récupéré -> url articles
urlsArticles = getData(liensArticles, source['selecteur_links']['operation'])
#4: pour chaque url article:
for urlArticle in urlsArticles:
#5: checker si l'url de l'article se trouve déjà dans la table article de la db. si il y est, skipper le reste des opérations
query = "SELECT * FROM article WHERE url='"+urlArticle+"'"
alreadyInDB = False
with db.cursor() as cursor:
cursor.execute(query)
result = cursor.fetchall()
if len(result) > 0:
alreadyInDB = True
if(alreadyInDB == True):
continue
#5bis: récupérer la source de la page désignée par l'url
# print(urlArticle)
sourceUrl = getSrcFromURL(urlArticle)
print(sourceUrl)
print(urlArticle)
# print(sourceUrl)
# #6: déclarer un tableau vide qui contiendra les éléments à insérer dans la db -> dataArticle
dataArticle = []
# #7: pour chaque sélecteur contenu dans "selecteurs_article":
for selecteur_article in source['selecteurs_article']:
# #8: appliquer le sélecteur article sur la source de la page
applySelector = getResults(sourceUrl, selecteur_article['selecteur'])
# print(applySelector)
# #9: appliquer l'opération sur l'élément récupéré -> donnée
operateelement = getData(applySelector, selecteur_article['operation'])
#10: ajouter la donnée au tableau dataArticle
dataArticle.append(operateelement)
print(dataArticle)
if(len(dataArticle[0]) == 0):
continue
#[['Les Etats-Unis et la Chine «\xa0s’engagent à coopérer\xa0» sur la crise climatique'], ['2021-04-18 02:33:09']]
# #11: insérer le tableau dans la base de données
query = "INSERT INTO article (titre, date_crea, url, source_id) VALUES ('"+dataArticle[0][0]+"', '"+dataArticle[1][0]+"', '"+urlArticle+"', '"+str(sourceId)+"')"
print(query)
# query = "INSERT INTO article (titre, date_crea, source_id) VALUES ('%s', '%s', 1)" % (dataArticle[0], dataArticle[1])
cursor = db.cursor()
cursor.execute(query)
db.commit()