web-dev-qa-db-fra.com

Scrapy: Enregistrer response.body en tant que fichier html?

Mon araignée fonctionne, mais je ne peux pas télécharger le corps du site Web que j'explore dans un fichier .html. Si j'écris self.html_fil.write ('test'), cela fonctionne très bien. Je ne sais pas comment convertir la tulpe en chaîne.

J'utilise Python 3.6

Araignée:

class ExampleSpider(scrapy.Spider):
    name = "example"
    allowed_domains = ['google.com']
    start_urls = ['http://google.com/']

    def __init__(self):
        self.path_to_html = html_path + 'index.html'
        self.path_to_header = header_path + 'index.html'
        self.html_file = open(self.path_to_html, 'w')

    def parse(self, response):
        url = response.url
        self.html_file.write(response.body)
        self.html_file.close()
        yield {
            'url': url
        }

Tracktrace:

Traceback (most recent call last):
  File "c:\python\python36-32\lib\site-packages\twisted\internet\defer.py", line
 653, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "c:\Users\kv\AtomProjects\example_project\example_bot\example_bot\spiders
\example.py", line 35, in parse
    self.html_file.write(response.body)
TypeError: write() argument must be str, not bytes
8
bonblow

Le problème réel est que vous obtenez du code octet. Vous devez le convertir au format chaîne. il existe de nombreuses façons de convertir l'octet au format chaîne. Vous pouvez utiliser

 self.html_file.write(response.body.decode("utf-8"))

au lieu de

  self.html_file.write(response.body)

vous pouvez également utiliser

  self.html_file.write(response.text)
11
Somil

La bonne façon est d'utiliser response.text, Et non response.body.decode("utf-8"). Pour citer documentation :

Gardez à l'esprit que Response.body Est toujours un objet octets. Si vous voulez la version unicode, utilisez TextResponse.text (Uniquement disponible dans TextResponse et sous-classes).

et

texte: corps de réponse, comme unicode.

Identique à response.body.decode(response.encoding), mais le résultat est mis en cache après le premier appel, vous pouvez donc accéder à response.text Plusieurs fois sans surcharge.

Remarque: unicode(response.body) n'est pas un moyen correct de convertir le corps de la réponse en unicode: vous utiliseriez le codage par défaut du système (généralement ascii) au lieu du codage de la réponse.

6
nirvana-msu

En prenant en considération les réponses ci-dessus, et en le rendant aussi Pythonic que possible en ajoutant l'utilisation de l'instruction with, l'exemple devrait être réécrit comme:

class ExampleSpider(scrapy.Spider):
    name = "example"
    allowed_domains = ['google.com']
    start_urls = ['http://google.com/']

    def __init__(self):
        self.path_to_html = html_path + 'index.html'
        self.path_to_header = header_path + 'index.html'

    def parse(self, response):
        with open(self.path_to_html, 'w') as html_file:
            html_file.write(response.text)
        yield {
            'url': response.url
        }

Mais le html_file ne sera accessible qu'à partir de la méthode parse.

2
Mariano Ruiz