J'essaie d'écrire un petit script qui extraira les balises du jeu Steam et les stockera dans un fichier csv. Le problème que j'ai actuellement est que je ne sais pas comment supprimer les balises html de ma sortie. Mon code est en dessous de
[u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tSurvival\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tShooter\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tMultiplayer\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tPvP\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tThird-Person Shooter\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tFPS\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tAction\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tBattle Royale\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tOnline Co-Op\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tTactical\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tCo-op\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tEarly Access\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tFirst-Person\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tViolent\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tStrategy\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tThird Person\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tCompetitive\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tTeam-Based\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tDifficult\t\t\t\t\t\t\t\t\t\t\t\t', u'\r\n\t\t\t\t\t\t\t\t\t\t\t\tSimulation\t\t\t\t\t\t\t\t\t\t\t\t'],
Ma classe d'article:
class SteamItem(scrapy.Item): #defining item fields url = scrapy.Field() gametitle = scrapy.Field() gametags = scrapy.Field()
Ma sortie ressemble alors à ceci:
from __future__ import absolute_import import scrapy from Example.items import SteamItem from scrapy.selector import HtmlXPathSelector class SteamSpider(scrapy.Spider): name = 'steamspider' allowed_domains = ['https://store.steampowered.com/app'] start_urls = ["https://store.steampowered.com/app/578080/PLAYERUNKNOWNS_BATTLEGROUNDS/",] def parse(self, response): hxs = HtmlXPathSelector(response) tags = hxs.xpath('//*[@id="game_highlights"]/div[1]/div/div[4]/div/div[2]') for sel in tags: item = SteamItem() item['gametags'] = sel.xpath('.//a/text()').extract() item['gametitle'] = sel.xpath('//html/body/div[1]/div[7]/div[3]/div[1]/div[2]/div[2]/div[2]/div/div[3]/text()').extract() yield item
7 Réponses :
La première chose à comprendre est que ce que vous essayez de supprimer ne sont pas des "balises HTML", mais simplement des espaces, dont la plupart dans votre cas sont des tabulations, avec quelques retours à la ligne. -titre que vous questionnez pour mieux exprimer cela.
En ce qui concerne la suppression des espaces, la bibliothèque HTML que vous utilisez peut fournir une fonction pour cela.
Si ce n'est pas le cas, ou en plus cas général de ce problème, les chaînes Python ont une méthode strip
(et quelques relations) qui renverra la chaîne avec tous les espaces de début et de fin supprimés. Ainsi, vous pouvez faire quelque chose comme:
item['field'] = sel.xpath('...').extract().strip()
Plus d'informations disponibles dans le manuel Python: https://docs.python.org/2/library/string.html#string.strip
.extract () renvoie une liste, vous ne pouvez pas appliquer strip () à une liste
Pour obtenir le titre et les balises en conséquence, vous pouvez essayer le script suivant. Pour vous débarrasser des tabulations et des espaces, vous devez utiliser .strip ()
sur .extract_first()
.
import scrapy class SteamSpider(scrapy.Spider): name = 'steamspider' start_urls = ["https://store.steampowered.com/app/578080/PLAYERUNKNOWNS_BATTLEGROUNDS/",] def parse(self, response): title = response.xpath("//*[@class='apphub_AppName']/text()").extract_first().strip() tag_name = [item.strip() for item in response.xpath('//*[contains(@class,"popular_tags")]/*[@class="app_tag"]/text()').extract()] yield {"title":title,"tagname":tag_name}
Sur un nouveau code, .get ()
peut être une alternative plus pythonique à .extract_first ()
.
item['gametags'] = [val.strip() for val in sel.xpath('.//a/text()').extract()]
Vous pouvez utiliser la méthode strip
. Puisque vous utilisez extract ()
qui renverra éventuellement une liste, vous pouvez essayer ceci.
item['gametags'] = list(map(str.strip, sel.xpath('.//a/text()').extract()) item['gametitle'] = list(map(str.strip, sel.xpath('//html/body/div[1]/div[7]/div[3]/div[1]/div[2]/div[2]/div[2]/div/div[3]/text()').extract())
Vous pouvez également suivre cet article de blog pour le grattage à la vapeur
p >
Utiliser strip ()
est une façon de le faire. Cependant, si vous souhaitez y parvenir entièrement en utilisant XPath, jetez un œil à normalize-space . Dans votre cas, modifiez simplement l'extraction des valeurs en:
item['gametags'] = [a.xpath('normalize-space(.)').extract_first() for a in sel.xpath('.//a')] item['gametitle'] = sel.xpath('normalize-space(//html/body/div[1]/div[7]/div[3]/div[1]/div[2]/div[2]/div[2]/div/div[3])').extract_first()
Utilisez simplement remove_tags
from scrapy.utils.markup import remove_tags ToRemove = remove_tags(YourOutPut) print(ToRemove)
Cela résoudra votre problème
Ce n'est plus recommandé: AVERTISSEMENT: scrapy.utils.markup
est obsolète. Veuillez plutôt importer depuis w3lib.html
.
Puisque vous utilisez le framework Scrapy, vous pouvez utiliser une bibliothèque fournie avec Scrapy appelée w3lib
import w3lib.html output= w3lib.html.remove_tags(input) print(output)
scrapy.utils.markup est dépréciée en 2019 et veuillez utiliser w3lib à la place.
Vous pouvez vous référer à https: // w3lib. readthedocs.io/en/latest/index.html pour plus d'informations.