Aula 43: O uso do Spider flexível e fácil de usar

Na última lição, aprendemos sobre o uso básico do Scrapy por meio de exemplos.Neste processo, usamos o Spider para escrever a lógica do crawler e alguns seletores para selecionar os resultados.

Nesta lição, vamos resumir o uso básico do Spider e do Selector.

Uso de aranha

No Scrapy, a configuração do link, a lógica de rastreamento, a lógica de análise, etc. para rastrear o site são configurados no Spider. No exemplo da lição anterior, descobrimos que a lógica de rastreamento também é feita no Spider. Nesta lição, entenderemos especificamente o uso básico do Spider.

Processo de execução do Spider

Ao implementar o projeto Scrapy crawler, a classe principal é a classe Spider, que define o processo e o método de análise de como rastrear um site. Para simplificar, o Spider precisa fazer as duas coisas a seguir:

  • Definir a ação de rastreamento do site;
  • Analise as páginas da web rastreadas.

Para a classe Aranha, todo o ciclo de rastreamento é o seguinte.

  • Inicialize a solicitação com o URL inicial e defina a função de retorno de chamada. Quando a Solicitação solicita e retorna com sucesso, uma Resposta será gerada e passada para a função de retorno de chamada como um parâmetro.
  • Analise o conteúdo da página da web retornado na função de retorno de chamada. O resultado retornado pode ter duas formas, uma é que o resultado efetivo da análise é retornado a um dicionário ou a um objeto Item. A próxima etapa pode ser processada (ou diretamente) salva e a outra é o próximo link (próxima página) que é analisado. Você pode usar esse link para construir uma Solicitação e definir uma nova função de retorno de chamada para retornar à Solicitação.
  • Se o retornado for um dicionário ou objeto Item, ele pode ser armazenado em um arquivo por meio de Exportações de Feed, etc. Se o Pipeline estiver definido, ele pode ser processado (como filtragem, correção, etc.) e salvo por meio do Pipeline.
  • Se a resposta for Reqeust, então a Solicitação será passada para a função de retorno de chamada definida na Solicitação novamente após a Resposta ser executada com sucesso, e o seletor pode ser usado novamente para analisar o conteúdo da web recém-obtido e gerar um Item com base nos dados analisados.

Ao repetir as etapas acima, o rastreamento do site é concluído.

Análise de classe de aranha

No exemplo da lição anterior, a Aranha que definimos herdada de scrapy.spiders.Spider. Esta classe é a classe Aranha mais simples e básica. Todas as outras Aranhas devem herdar desta classe, bem como algumas outras especiais que serão explicadas posteriormente. A classe Spider também herda disso.

Esta classe fornece a implementação padrão do método start_requests, lê e solicita o atributo start_urls e chama o método parse para analisar o resultado de acordo com o resultado retornado. Além disso, possui algumas propriedades básicas, que são explicadas a seguir.

  • nome : o nome da aranha, uma string que define o nome da aranha. O nome da Aranha define como Scrapy localiza e inicializa a Aranha, por isso deve ser único. No entanto, podemos gerar várias instâncias do Spider idênticas sem quaisquer restrições. O nome é o atributo mais importante da Aranha e é obrigatório. Se o spider rastreia um único site, uma prática comum é nomear o spider pelo nome de domínio do site. Por exemplo, se um Spider rastreia mywebsite.com, o Spider geralmente será nomeado mywebsite.

  • permission_domains : Os nomes de domínio que podem ser rastreados são opcionais. Os links que não estiverem neste intervalo não serão rastreados.

  • start_urls : lista de URLs de início, quando não implementarmos o método start_requests, começaremos a rastrear a partir desta lista por padrão.

  • custom_settings : Este é um dicionário exclusivo para a configuração deste Spider.Esta configuração irá sobrescrever as configurações globais do projeto, e esta configuração deve ser atualizada antes da inicialização, portanto deve ser definida como uma variável de classe.

  • crawler : Este atributo é definido pelo método from_crawler, que representa o objeto Crawler correspondente a esta classe Spider. O objeto Crawler contém muitos componentes do projeto. Podemos usá-lo para obter algumas informações de configuração do projeto. Por exemplo, o mais comum é obter o projeto Informações de configuração, nomeadamente Configurações.

  • settings : é um objeto Settings, com o qual podemos obter diretamente as variáveis ​​de configurações globais do projeto.

Além de algumas propriedades básicas, o Spider também possui alguns métodos comumente usados, que são apresentados aqui.

  • start_requests : Este método é usado para gerar a solicitação inicial.Ele deve retornar um objeto iterável.Este método usará a URL em start_urls para construir a solicitação por padrão, e a solicitação é um método de solicitação GET. Se quisermos acessar um determinado site por POST na inicialização, podemos substituir diretamente este método e usar FormRequest ao enviar solicitações POST.

  • parse : Quando o Response não especifica uma função de callback, este método será chamado por padrão.Ele é responsável por processar a Response, processar o resultado retornado e extrair os dados desejados e a próxima solicitação dele, e então retornar. Este método precisa retornar um objeto iterável contendo Request ou Item.

  • fechado : Quando o Spider é fechado, este método será chamado, onde algumas operações para liberar recursos ou outras operações de fechamento são geralmente definidas.

Uso do seletor

Anteriormente, introduzimos o uso de Beautiful Soup, PyQuery e expressões regulares para extrair dados de páginas da web, o que é realmente muito conveniente. E o Scrapy também fornece seu próprio método de extração de dados, chamado Seletor (seletor).

O Seletor é construído com base em lxml, suporta seletor XPath, seletor CSS e expressões regulares, com funções abrangentes, velocidade de alta resolução e precisão.

A seguir, apresentaremos o uso do Seletor.

Use diretamente

Seletor é um módulo que pode ser usado de forma independente. Podemos usar diretamente a classe Selector para construir um objeto seletor e, em seguida, chamar seus métodos relacionados, como xpath, css, etc. para extrair dados.

Por exemplo, para um trecho de código HTML, podemos construir um objeto Seletor para extrair dados da seguinte maneira:

from scrapy import Selector
body = '<html><head><title>Hello World</title></head><body></body></html>'
selector = Selector(text=body)
title = selector.xpath('//title/text()').extract_first()
print(title)

resultado da operação:

Hello World

Aqui não executamos no framework Scrapy, mas usamos o Seletor no Scrapy separadamente. Passando o parâmetro de texto durante a construção, um objeto Seletor Seletor é gerado, e então pode ser como aquele no Scrapy que usamos anteriormente O método de análise é o mesmo, chamando xpath, css e outros métodos para extrair.

Aqui, estamos procurando o texto do título no código-fonte. Adicione o método de texto no final do seletor XPath para extrair o texto.

O conteúdo acima é de uso direto do Selector. Semelhante a bibliotecas como Beautiful Soup, Selector é, na verdade, uma poderosa biblioteca de análise da web. Se for conveniente, também podemos usar o Seletor diretamente para extrair dados em outros projetos.

A seguir, usamos exemplos para explicar o uso do Seletor em detalhes.

Scrapy Shell

Como o Selector é usado principalmente em combinação com o Scrapy, por exemplo, a resposta do parâmetro na função de retorno de chamada do Scrapy chama diretamente o método xpath () ou css () para extrair dados, então aqui usamos o Scrapy Shell para simular o processo de solicitação do Scrapy para explicar o relacionado método de extração.

Usamos uma página de amostra do documento oficial para demonstrar: http://doc.scrapy.org/en/latest/_static/selectors-sample1.html .

Abra o Scrapy Shell e digite o seguinte comando na linha de comando:

scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html

Então, entramos no modo Scrapy Shell. Na verdade, esse processo é que o Scrapy inicia uma solicitação. A URL solicitada é a URL inserida na linha de comando agora, e então algumas variáveis ​​operáveis ​​são passadas para nós, como solicitação, resposta, etc., conforme mostrado na figura.

Insira a descrição da imagem aqui
Podemos inserir comandos no modo de linha de comando para chamar alguns métodos de operação do objeto e, em seguida, pressionar Enter para exibir os resultados em tempo real. Isso é semelhante ao modo interativo de linha de comando do Python.

A seguir, todos os exemplos de demonstração usam o código-fonte da página como o alvo da análise. O código-fonte da página é o seguinte:

<html>
 <head>
  <base href='http://example.com/' />
  <title>Example website</title>
 </head>
 <body>
  <div id='images'>
   <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
   <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
   <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
   <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
   <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
  </div>
 </body>
</html>

Seletor XPath

Depois de entrar no Scrapy Shell, manipularemos principalmente a variável de resposta para análise. Como estamos analisando o código HTML, o Selector usará automaticamente a sintaxe HTML para analisar.

A resposta tem um seletor de atributos. O conteúdo retornado pela chamada de response.selector é equivalente a construir um objeto Seletor com o texto da resposta. Por meio desse objeto Seletor, podemos chamar métodos de análise, como xpath, css, etc., e extrair informações passando em XPath ou parâmetros do seletor CSS para o método.

Vamos experimentar com um exemplo, conforme mostrado abaixo:

>>> result = response.selector.xpath('//a')
>>> result
[<Selector xpath='//a' data='<a href="image1.html">Name: My image 1 <'>,
 <Selector xpath='//a' data='<a href="image2.html">Name: My image 2 <'>,
 <Selector xpath='//a' data='<a href="image3.html">Name: My image 3 <'>,
 <Selector xpath='//a' data='<a href="image4.html">Name: My image 4 <'>,
 <Selector xpath='//a' data='<a href="image5.html">Name: My image 5 <'>]
>>> type(result)
scrapy.selector.unified.SelectorList

A forma do resultado impresso é uma lista composta por Selector. Na verdade, é do tipo SelectorList. Tanto SelectorList quanto Selector podem continuar a chamar métodos como xpath e css para extrair dados posteriormente.

No exemplo acima, extraímos um nó. Em seguida, tentamos continuar chamando o método xpath para extrair o nó img contido no nó a, conforme mostrado abaixo:

>>> result.xpath('./img')
[<Selector xpath='./img' data='<img src="image1_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image2_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image3_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image4_thumb.jpg">'>,
 <Selector xpath='./img' data='<img src="image5_thumb.jpg">'>]

Temos todos os nós img no nó a e o resultado é 5.

É importante ressaltar que o ponto (ponto) é adicionado à frente do seletor, o que significa extrair os dados dentro do elemento, se nenhum ponto for adicionado, significa extrair do nó raiz. Aqui usamos o método de extração de ./img, o que significa extrair de um nó. Se usarmos // img aqui, ainda o extrairemos do nó html.

Acabamos de usar o método response.selector.xpath para extrair os dados. O Scrapy fornece dois atalhos práticos, response.xpath e response.css, suas funções são completamente equivalentes a response.selector.xpath e response.selector.css. Por conveniência, chamaremos diretamente os métodos de resposta xpath e css para fazer seleções.

Agora o que obtemos é uma variável do tipo SelectorList, que é uma lista de objetos Selector. Podemos usar o índice para recuperar um dos elementos do Seletor individualmente, conforme mostrado abaixo:

>>> result[0]
<Selector xpath='//a' data='<a href="image1.html">Name: My image 1 <'>

Podemos manipular este SelectorList como uma lista. Mas agora o conteúdo obtido é do tipo Selector ou SelectorList, não o conteúdo de texto real. Então, como extrair conteúdo específico?
Por exemplo, se quisermos extrair o elemento de um nó, podemos usar o método extract, conforme mostrado abaixo:

>>> result.extract()
['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>', '<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>', '<a href="image3.html">Name: My image 3 <br><img src="image3_thumb.jpg"></a>', '<a href="image4.html">Name: My image 4 <br><img src="image4_thumb.jpg"></a>', '<a href="image5.html">Name: My image 5 <br><img src="image5_thumb.jpg"></a>']

Usando o método extract aqui, podemos obter o que realmente precisamos.

Também podemos reescrever a expressão XPath para selecionar o texto interno e os atributos do nó, conforme mostrado abaixo:

>>> response.xpath('//a/text()').extract()
['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 ']
>>> response.xpath('//a/@href').extract()
['image1.html', 'image2.html', 'image3.html', 'image4.html', 'image5.html']

Precisamos apenas adicionar outra camada de / text () para obter o texto interno do nó, ou adicionar uma camada de / @ href para obter o atributo href do nó. Dentre eles, o conteúdo após o símbolo @ é o nome do atributo a ser obtido.

Agora podemos usar uma regra para obter todos os nós que atendem aos requisitos, e o tipo retornado é um tipo de lista.

Mas há um problema: se houver apenas um nó que atenda aos requisitos, qual será o resultado retornado? Vamos usar outro exemplo para sentir isso, conforme mostrado abaixo:

>>> response.xpath('//a[@href="image1.html"]/text()').extract()
['Name: My image 1 ']

Usamos atributos para limitar o escopo de correspondência de forma que XPath possa corresponder apenas a um elemento. Em seguida, use o método extract para extrair o resultado, o resultado ainda está na forma de uma lista e seu texto é o primeiro elemento da lista. Mas, em muitos casos, os dados que realmente queremos são o conteúdo do primeiro elemento. Aqui, nós os obtemos adicionando um índice, conforme mostrado abaixo:

'Name: My image 1 '

No entanto, essa escrita é obviamente arriscada. Uma vez que haja um problema com XPath, o resultado da extração pode ser uma lista vazia. Se usarmos o índice para obter, isso não fará com que o array saia dos limites?
Portanto, outro método pode extrair especificamente um único elemento, é chamado extract_first. Podemos reescrever o exemplo acima da seguinte maneira:

>>> response.xpath('//a[@href="image1.html"]/text()').extract_first()
'Name: My image 1 '

Desta forma, usamos diretamente o método extract_first para extrair o primeiro resultado da correspondência e não precisamos nos preocupar com o problema de array fora dos limites.

Além disso, também podemos definir um parâmetro de valor padrão para o método extract_first, de modo que quando a regra XPath não puder extrair o conteúdo, o valor padrão será usado diretamente. Por exemplo, altere XPath para uma regra inexistente e execute novamente o código, conforme mostrado abaixo:

>>> response.xpath('//a[@href="image1"]/text()').extract_first()>>> response.xpath('//a[@href="image1"]/text()').extract_first('Default Image')
'Default Image'

Aqui, se XPath não corresponder a nenhum elemento, chamar extract_first retornará nulo e nenhum erro será relatado. Na segunda linha do código, também passamos um parâmetro como o valor padrão, como Imagem Padrão. Dessa forma, se o XPath não corresponder ao resultado, o valor de retorno usará esse parâmetro, e você pode ver que a saída é exatamente a mesma.

Até agora, entendemos o uso relacionado de XPath no Scrapy, incluindo consultas aninhadas, extração de conteúdo, extração de conteúdo único, obtenção de texto e atributos, etc.

Seletor CSS

A seguir, vamos examinar o uso de seletores CSS. Os seletores do Scrapy também se encaixam nos seletores CSS. Use o método response.css () para usar os seletores CSS para selecionar os elementos correspondentes.

Por exemplo, no exemplo acima, selecionamos todos os nós, então o seletor CSS também pode fazer isso, conforme mostrado abaixo:

>>> response.css('a')
[<Selector xpath='descendant-or-self::a' data='<a href="image1.html">Name: My image 1 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image2.html">Name: My image 2 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image3.html">Name: My image 3 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image4.html">Name: My image 4 <'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image5.html">Name: My image 5 <'>]

Da mesma forma, o nó pode ser extraído chamando o método de extração, conforme mostrado abaixo:

['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>', '<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>', '<a href="image3.html">Name: My image 3 <br><img src="image3_thumb.jpg"></a>', '<a href="image4.html">Name: My image 4 <br><img src="image4_thumb.jpg"></a>', '<a href="image5.html">Name: My image 5 <br><img src="image5_thumb.jpg"></a>']

O uso e a seleção XPath são exatamente os mesmos. Além disso, também podemos realizar a seleção de atributos e a seleção aninhada, conforme mostrado abaixo:

>>> response.css('a[href="image1.html"]').extract()
['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>']
>>> response.css('a[href="image1.html"] img').extract()
['<img src="image1_thumb.jpg">']

Aqui, [href = ”image.html”] é usado para limitar o atributo href, você pode ver que há apenas um resultado correspondente. Além disso, se você quiser encontrar o nó img em um nó, você só precisa adicionar um espaço e img. O seletor é escrito exatamente da mesma maneira que o seletor CSS padrão.

Também podemos usar o método extract_first () para extrair o primeiro elemento da lista, conforme mostrado abaixo:

>>> response.css('a[href="image1.html"] img').extract_first()
'<img src="image1_thumb.jpg">'

Os próximos dois usos não são os mesmos. O texto interno e os atributos do nó são obtidos desta forma, conforme mostrado abaixo:

>>> response.css('a[href="image1.html"]::text').extract_first()
'Name: My image 1 '
>>> response.css('a[href="image1.html"] img::attr(src)').extract_first()
'image1_thumb.jpg'

Para obter texto e atributos, você precisa usar :: text e :: attr (). Outras bibliotecas, como Beautiful Soup ou PyQuery, possuem métodos separados.

Além disso, os seletores CSS podem aninhar seleções da mesma forma que os seletores XPath. Podemos primeiro usar o seletor XPath para selecionar todos os nós, então usar o seletor CSS para selecionar o nó img e então usar o seletor XPath para obter atributos. Vamos experimentar com um exemplo, conforme mostrado abaixo:

>>> response.xpath('//a').css('img').xpath('@src').extract()
['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']

Obtivemos com sucesso os atributos src de todos os nós img.
Portanto, podemos usar livremente os métodos xpath e css para obter consultas aninhadas, e os dois são totalmente compatíveis.

Partida regular

O seletor de Scrapy também suporta correspondência regular. Por exemplo, o texto no nó a do exemplo é semelhante a Nome: Minha imagem 1. Agora, queremos apenas extrair o conteúdo após Nome :. Neste momento, podemos usar o método re para obter o seguinte:

>>> response.xpath('//a/text()').re('Name:\s(.*)')
['My image 1 ', 'My image 2 ', 'My image 3 ', 'My image 4 ', 'My image 5 ']

Passamos uma expressão regular para o método re, onde (. *) É o conteúdo a ser correspondido, o resultado de saída é o grupo correspondido pela expressão regular e o resultado será enviado por sua vez.

Se houver dois grupos ao mesmo tempo, os resultados ainda serão exibidos em ordem, conforme mostrado abaixo:

>>> response.xpath('//a/text()').re('(.*?):\s(.*)')
['Name', 'My image 1 ', 'Name', 'My image 2 ', 'Name', 'My image 3 ', 'Name', 'My image 4 ', 'Name', 'My image 5 ']

Semelhante ao método extract_first, o método re_first pode selecionar o primeiro elemento da lista. O uso é o seguinte:

>>> response.xpath('//a/text()').re_first('(.*?):\s(.*)')
'Name'
>>> response.xpath('//a/text()').re_first('Name:\s(.*)')
'My image 1 '

Não importa quantos grupos correspondam à regex, o resultado será igual ao primeiro elemento da lista.

É importante notar que o objeto de resposta não pode chamar diretamente os métodos re e re_first. Se você deseja realizar a correspondência regular no texto completo, pode primeiro chamar o método xpath e, em seguida, realizar a correspondência regular, conforme mostrado abaixo:

>>> response.re('Name:\s(.*)')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'HtmlResponse' object has no attribute 're'
>>> response.xpath('.').re('Name:\s(.*)<br>')
['My image 1 ', 'My image 2 ', 'My image 3 ', 'My image 4 ', 'My image 5 ']
>>> response.xpath('.').re_first('Name:\s(.*)<br>')
'My image 1 '

Por meio do exemplo acima, podemos ver que chamar o método re diretamente fará com que não haja nenhum atributo re. Mas aqui primeiro chamamos xpath ('.') Para selecionar o texto completo e, em seguida, chamamos os métodos re e re_first para realizar a correspondência regular.

O conteúdo acima é o uso do seletor Scrapy, que inclui dois seletores comuns e funções de correspondência regulares. Se você for proficiente na sintaxe XPath, sintaxe do seletor CSS e sintaxe de expressão regular, a eficiência da extração de dados pode ser bastante melhorada.

Acho que você gosta

Origin blog.csdn.net/weixin_38819889/article/details/107974075
Recomendado
Clasificación