1
votes

Impossible d'atteindre certains textes situés en dehors des éléments ciblés

J'ai écrit un script en scrapy pour récupérer les réponses à différentes questions sur une page Web. Le problème est que les réponses sont en dehors des éléments que je cible actuellement. Je sais que je pourrais les récupérer en utilisant .next_sibling si j'utilisais pour BeautifulSoup mais en cas de scrapy, je ne trouve aucune idée.

lien vers le site Web

Les éléments HTML sont comme:

It initiates the risk that malicious software is targeting the VM environment.

J'ai essayé jusqu'à présent avec:

import requests
from scrapy import Selector

url = "https://www.test-questions.com/csslp-exam-questions-01.php"

res = requests.get(url,headers={"User-Agent":"Mozilla/5.0"})
sel = Selector(res)
for item in sel.css("[name^='quest']::text").getall():
    print(item)

Le script ci-dessus n'imprime rien lorsqu'il est exécuté, il ne génère aucune erreur non plus. p>

L'une des sorties attendues des éléments html collés ci-dessus est:

  <p>
   <b>
    <span class="blue">
     Q:1-The NIST Information Security and Privacy Advisory Board (ISPAB) paper "Perspectives on Cloud Computing and Standards" specifies potential advantages and disdvantages of virtualization. Which of the following disadvantages does it include?
    </span>
    <br/>
    Mark one answer:
   </b>
   <br/>
   <input name="quest1" type="checkbox" value="1"/>
   It initiates the risk that malicious software is targeting the VM environment.
   <br/>
   <input name="quest1" type="checkbox" value="2"/>
   It increases overall security risk shared resources.
   <br/>
   <input name="quest1" type="checkbox" value="3"/>
   It creates the possibility that remote attestation may not work.
   <br/>
   <input name="quest1" type="checkbox" value="4"/>
   All of the above
  </p>

Je ne recherche que n'importe quelle solution de sélecteur css. em>

Comment puis-je obtenir les réponses à différentes questions de ce site?


1 commentaires

Pourriez-vous nous dire pourquoi CSS uniquement?


3 Réponses :


0
votes

Vous pouvez essayer d'obtenir du texte après les balises sous la forme following-sibling :: text () . Vérifiez cet exemple:

>>> sel.css("[name^='quest']").xpath('./following-sibling::text()').extract()
[u'\n   It initiates the risk that malicious software is targeting the VM environment.\n   ', u'\n   ', u'\n   It increases overall security risk shared resources.\n   ', u'\n   ', u'\n   It creates the possibility that remote attestation may not work.\n   ', u'\n   ', u'\n   All of the above\n  ', u'\n   It increases overall security risk shared resources.\n   ', u'\n   ', u'\n   It creates the possibility that remote attestation may not work.\n   ', u'\n   ', u'\n   All of the above\n  ', u'\n   It creates the possibility that remote attestation may not work.\n   ', u'\n   ', u'\n   All of the above\n  ', u'\n   All of the above\n  ']


1 commentaires

Merci @vezunchik pour votre solution. Le truc, c'est que je le sais déjà et j'ai créé ce post pour rechercher toute solution liée au sélecteur css. Merci.



0
votes

Vous ne pouvez pas faire cela pour le moment en utilisant uniquement CSS.

cssselect , la bibliothèque sous-jacente derrière response.css () , ne prend pas en charge la sélection de texte frère.

Vous pouvez tout au plus sélectionner le premier élément suivant:

>>> selector.css('[name^="quest"] + *').get()
'<br>'

p>


0 commentaires

1
votes

La combinaison suivante de sélecteurs css simples et de fonctions de liste python peut résoudre cette tâche:

import scrapy
from scrapy.crawler import CrawlerProcess

class QuestionsSpider(scrapy.Spider):
    name = "TestSpider"
    start_urls = ["https://www.test-questions.com/csslp-exam-questions-01.php"]

    def parse(self,response):
    #select <p> tag elements with questions/answers
        questions_p_tags = [ p for p in response.css("form p")
                             if '<span class="blue"' in p.extract()]
        for p in questions_p_tags:
    #select question and answer variants inside every <p> tag
            item = dict()
            item["question"] = p.css("span.blue::text").extract_first()
    #following list comprehension - select all text, filter empty text elements
    #and select last 4 text elements as answer variants
            item["variants"] = [variant.strip() for variant in p.css("::text").extract() if variant.strip()][-4:]
            yield item

if __name__ == "__main__":
    c = CrawlerProcess({'USER_AGENT':'Mozilla/5.0'})
    c.crawl(QuestionsSpider)
    c.start()


1 commentaires

Pourriez-vous jeter un œil à ce post au cas où il y aurait une solution à offre @Georgiy. Merci.