- pySpider
Qu'est-ce qu'un framework ?
- C'est un modèle de projet hautement réutilisable intégrant plusieurs fonctionnalités (applicable à divers besoins)
Fonctionnalités intégrées par Scrapy :
- Opérations d'analyse de données performantes (XPath)
- Téléchargement de données haute performance
- Stockage persistant hautement efficace
- Middleware
- Opérations complètes de scraping
- Distribution : Redis
- Mécanisme de passage de paramètres dans les requêtes (crawl en profondeur)
- Intégration raisonnable de Selenium dans Scrapy
Installation de l'environnement :
pip3 install wheel- Télécharger Twisted depuis http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted
- Dans le dossier de téléchargement, exécuter
pip3 install Twisted‑17.1.0‑cp35‑cp35m‑win_amd64.whl pip3 install pywin32pip3 install scrapy
Création d'un projet :
scrapy startproject ProNamecd ProNamescrapy genspider spiderName www.xxx.com: création d'un fichier spider- Exécution :
scrapy crawl spiderName - Paramètres (
settings) :- Ne pas respecter le fichier robots.txt
- Usurpation d'UA
LOG_LEVEL = 'ERROR'LOG_FILE = 'logging.log'
Extraction des données avec Scrapy :
extract(): retourne une liste de résultatsextract_first(): retourne uniquement le premier résultat
Stockage persistant avec Scrapy :
- Via commandes terminales :
- Seulement les retours de la méthode
parsepeuvent être sauvegardés sur le disque scrapy crawl first -o file.csv
- Seulement les retours de la méthode
- Via pipelines (
pipelines.py) :- Processus de codage :
- Extraction des données
- Définition des attributs dans la classe Item
- Encapsulation des données extraites dans un objet de type Item :
item['p'] - Transmission de l'objet Item au pipeline
- Méthode
process_itemdu pipeline reçoit l'objet Item pour un stockage persistant selon les besoins - Activation du pipeline dans le fichier de configuration
- Processus de codage :
Remarques :
- Chaque classe pipeline représente un type spécifique de stockage.
- Si plusieurs classes sont définies, l'objet Item est transmis à celle ayant la priorité la plus élevée.
- Retourner
itemdansprocess_itempermet de transmettre l'objet au pipeline suivant.
Exemple : Récupération des noms, pseudos et popularité des streams sur HuYa
Première méthode de stockage (via terminal)
Code de l'instance hy.py :
# -*- coding: utf-8 -*-
import scrapy
class HySpider(scrapy.Spider):
name = 'hy'
# allowed_domains = ['www.xx.com']
start_urls = ['https://www.huya.com/g/3203']
def parse(self, response):
li_list = response.xpath('//*[@id="js-live-list"]/li')
data = []
for li in li_list:
title = li.xpath("./a[2]/text()").extract_first()
nick = li.xpath("./span/span[1]/i/text()").extract_first()
hot = li.xpath("./span/span[2]/i[2]/text()").extract_first()
dic = {"title": title, "nick": nick, "hot": hot}
data.append(dic)
return data
Dans le terminal de PyCharm, exécuter la commande : scrapy crawl hy -o huya.csv
Deuxième méthode de stockage (via pipeline)
Code hy.py :
# -*- coding: utf-8 -*-
import scrapy
from huya.items import HuyaItem
class HySpider(scrapy.Spider):
name = 'hy'
# allowed_domains = ['www.xx.com']
start_urls = ['https://www.huya.com/g/3203']
def parse(self, response):
li_list = response.xpath('//*[@id="js-live-list"]/li')
for li in li_list:
title = li.xpath("./a[2]/text()").extract_first()
nick = li.xpath("./span/span[1]/i/text()").extract_first()
hot = li.xpath("./span/span[2]/i[2]/text()").extract_first()
item = HuyaItem()
item["title"] = title
item["nick"] = nick
item["hot"] = hot
yield item
Classe Item :
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class HuyaItem(scrapy.Item):
title = scrapy.Field()
nick = scrapy.Field()
hot = scrapy.Field()
Classe Pipeline (stockage local et MySQL) :
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import pymysql
class HuyaPipeline(object):
def open_spider(self, spider):
print("open_spider start work...")
self.fp = open("huya.txt", "w", encoding="utf-8")
def process_item(self, item, spider):
self.fp.write(item["title"] + "--" + item["nick"] + "--" + item["hot"] + "\n")
print(item["title"] + ": stockage terminé...")
return item
def close_spider(self, spider):
print("close_spider end work...")
self.fp.close()
class mysqlPipeline(object):
def open_spider(self, spider):
print("open_spider start work...")
self.conn = pymysql.Connect(host="127.0.0.1", port=3306, user="root", password="root", db="Spider", charset="utf8")
def process_item(self, item, spider):
sql = "insert into huya values ('%s','%s','%s')" % (item["title"], item["nick"], item["hot"])
self.cursor = self.conn.cursor()
try:
self.cursor.execute(sql)
self.conn.commit()
except Exception as e:
self.conn.rollback()
return item
def close_spider(self, spider):
print("close_spider end work...")
Modification nécessaire dans settings.py :
ITEM_PIPELINES = {
'huya.pipelines.HuyaPipeline': 300,
'huya.pipelines.mysqlPipeline': 301
}
Pour synchroniser avec Redis, ajouter cette classe dans le pipeline :
class RedisPipeLine(object):
conn = None
def open_spider(self, spider):
self.conn = Redis(host='127.0.0.1', port=6379)
def process_item(self, item, spider):
self.conn.lpush('huyaList', item)
return item
Modifier ITEM_PIPELINES dans settings.py pour inclure cette classe.