Scrapy cannot select a form using xpath

Asked

Viewed 221 times

3

Hello, I am using the scrapy to make a Crawler to get to pick up questions of concuros and etc from the site gabarite.com.br, I can get the description of the question the correct alternative, but I can not take the alternatives every time I run in the terminal the return of the alternatives and null, I do not know how to proceed could help me?

        # -*- coding: utf-8 -*-
        import scrapy
        import re
        from enemGrabData.items import EnemgrabdataItem
        class MultipleSpider(scrapy.Spider):
            name = 'multiple'
            allowed_domains = ['www.gabarite.com.br']
            start_urls = ['http://www.gabarite.com.br/questoes-de-concursos/disciplina/1-portugues']
            # html body div.site div#content
            def parse(self, response):

                conteudo = response.xpath('//*[@id="content_questoes_conteudo"]')
                item = EnemgrabdataItem();
                for questao in conteudo.xpath('ul'):
                    item['pergunta'] = questao.xpath('li[4]/text()').extract()
                    item['alternativa_A'] = questao.xpath('form/li/fieldset').extract()
                    # //*[@id="content_questoes_conteudo"]/ul[10]/form/li/fieldset
                    item['alternativa_B'] = questao.xpath('/form/li/fieldset/label[2]/text()').extract()
                    item['alternativa_C'] = questao.xpath('/form/li/fieldset/label[3]/text()').extract()
                    item['alternativa_D'] = questao.xpath('/form/li/fieldset/label[4]/text()').extract()
                    item['alternativa_E'] = questao.xpath('/form/li/fieldset/label[5]/text()').extract()
                    item['alternativaCorreta'] = questao.xpath('//form/button/@onclick').extract()
                    inputString = str(item['alternativaCorreta']).split("checaquestao",1)[1]
                    item['alternativaCorreta'] = str(inputString).split(',')[1]

                    # re.findall(r"\(u'(.*?)',\)", inputString)[0]
                       yield item

    <ul>
            <li class="numero"><h3>Questão 5104. &nbsp; <a href="questoes-de-concursos/disciplina/1-portugues">Português</a> - Nível Superior - Polícia Militar GO - UEG - 2013</h3></li>

                <li><a style="cursor:pointer; margin-top:10px; display:inline-block;" onclick="onoff('teste5104')"><img src="imagem/texto-questao.gif" alt="Texto anexado à questão" width="10" height="10"> Texto anexado à questão</a></li>
                <li class="texto" style="display:none;margin-top:5px;" id="teste5104"> <img width="680" height="754" alt="Violência no Brasil, outro olhar" src="http://www.gabarite.com.br/midia/questoes/689-texto.fw.png"></li>

            <li class="pergunta">A expressão “tais como” (linha 3) tem, no texto, a função de introduzir uma
    </li>
            <form name="form-questoes"> 

                <li class="questao">
                    <fieldset>
                    <span><input id="a5104" type="radio" name="radio5104" value="a"></span><label for="a5104">a) concessão</label>
                    <span><input id="b5104" type="radio" name="radio5104" value="b"></span><label for="b5104">b) exemplificação</label>
                    <span><input id="c5104" type="radio" name="radio5104" value="c"></span><label for="c5104">c) conclusão</label>
                    <span><input id="d5104" type="radio" name="radio5104" value="d"></span><label for="d5104">d) exceção</label>        

                    </fieldset>
                </li>
                <button title="Gabarito com resposta certa." name="botao5104" class="btn" type="button" onclick="checaquestao(5104,'b','mult-escolha')">Resolver questão</button>   

            <span id="msg5104"></span>  
            </form> 
            <li class="comentario">
        <ul>
        <li><a rel="nofollow" title="Explique esta questão!" href="javascript:abre_janela('http://www.gabarite.com.br/questoes-de-concursos/questao/5104',500,600)">Comentar questão</a></li>   
        <li><a rel="nofollow" title="Comentários sobre a questão!" href="javascript:abre_janela('http://www.gabarite.com.br/questoes-de-concursos/questao/5104',500,600)">0 comentários</a></li>
        <li><a rel="nofollow" title="Gabarito errado, está desatualizada, foi anulada pela banca, problemas na formatação, etc..." href="javascript:abre_janela('http://www.gabarite.com.br/questoes_aviso.asp?id_questao=5104',500,600)">Notificar erro</a></li>

        </ul>
    </li>
            </ul>

1 answer

2


I think this example is useful to you. I haven’t covered every possible case. There are issues of right and wrong that I haven’t tried. But since your problem was to take the alternatives, this example should give you a good idea of how to proceed. The identification of the last page is based on the non-existence of the 'Last' button. It is a weak check but serves as an example.

# -*- coding: utf-8 -*-
from lxml import html


def parse(tree):
    conteudo = tree.xpath('//*[@id="content_questoes_conteudo"]')[0]
    forms = conteudo.xpath('form')
    for idx, questao in enumerate(conteudo.xpath('ul')):
        item = {}
        if len(questao.xpath('li[@class="numero"]')):
            item['questao'] = questao.xpath('li[@class="numero"]')[0].text_content()

        if len(questao.xpath('li[@class="texto"]')):
            item['texto'] = questao.xpath('li[@class="texto"]')[0].text_content()

        if len(questao.xpath('li[@class="pergunta"]')):
            item['pergunta'] = questao.xpath('li[@class="pergunta"]')[0].text_content()

        alternativas = forms[idx].xpath('li/fieldset/label')

        item['alternativa_A'] = alternativas[0].text if len(alternativas) > 0 else ''
        item['alternativa_B'] = alternativas[1].text if len(alternativas) > 1 else ''
        item['alternativa_C'] = alternativas[2].text if len(alternativas) > 2 else ''
        item['alternativa_D'] = alternativas[3].text if len(alternativas) > 3 else ''
        item['alternativa_E'] = alternativas[4].text if len(alternativas) > 4 else ''

        item['alternativaCorreta'] = forms[idx].xpath('button/@onclick')[0]
        inputString = str(item['alternativaCorreta']).split("checaquestao", 1)[1]
        item['alternativaCorreta'] = str(inputString).split(',')[1]

        yield item


template_url = "http://www.gabarite.com.br/questoes-de-concursos/?id_materia={}&id_categoria=&nivel=&orgao=&assunto=&pagina={}"

possui_mais_paginas = True
pagina_atual = 1
id_materia = 1  # portugues

while possui_mais_paginas:
    possui_mais_paginas = False  # chuta que é a ultima pagina

    tree = html.parse(template_url.format(id_materia, pagina_atual))

    for item in parse(tree):
        print(item['alternativa_A'].strip())

    encontrou_botao_ultima = False
    for link in tree.xpath('//*[@id="content_paginacao"]/a'):
        if 'Última' in link.text:
            possui_mais_paginas = True  # se não é a ultima página vai para a proxima
            pagina_atual += 1
  • As I could tell to agoritimo to go to the next page, on scrapy and done with two lines, I tried in this code that you passed me importing the libs but it did not work so far

  • I edited to include paging and passing parameters like, matter. I hope it helps. Anyway, you can also edit your code in scrapy and include the xpath queries that I used in mine. It should work perhaps with small adaptations.

  • I got through your example to do using scrapy, thanks for the help, if you want to see how it turned out leave the link https://github.com/jpaulo789b/Crawler-Quest-es-Enem/blob/master/indo/spiders/spiderquestoes.py

Browser other questions tagged

You are not signed in. Login or sign up in order to post.