Webscraping текст возвращает пустой набор - PullRequest
0 голосов
/ 04 октября 2019

Код не записывает текст при использовании Beautiful Soup FindAll, поскольку возвращает пустой набор. После этого есть другие проблемы с кодом, но на этом этапе я пытаюсь решить первую проблему. Я довольно новичок в этом, поэтому я понимаю, что структура кода может быть не идеальной. Я родом из VBA.

import requests
from requests import get
from selenium import webdriver
from bs4 import BeautifulSoup
from lxml import html
import pandas as pd
#import chromedriver_binary  # Adds chromedriver binary to path

options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--incognito')
options.add_argument('--headless')
driver = webdriver.Chrome(executable_path=r"C:\Users\mmanenica\Documents\chromedriver.exe")

#click the search button on Austenders to return all Awarded Contracts
import time
#define the starting point: Austenders Awarded Contracts search page
driver.get('https://www.tenders.gov.au/cn/search')
#Find the Search Button and return all search results
Search_Results = driver.find_element_by_name("SearchButton")
if 'inactive' in Search_Results.get_attribute('name'):
    print("Search Button not found")
    exit;
print('Search Button found')
Search_Results.click()    

#Pause code to prevent blocking by website
time.sleep(1)
i = 0
Awarded = []

#Move to the next search page by finding the Next button at the bottom of the page
#This code will need to be refined as the last search will be skipped currently.
while True:
    Next_Page = driver.find_element_by_class_name('next')
    if 'inactive' in Next_Page.get_attribute('class'):
        print("End of Search Results")
        exit;  
    i = i + 1
    time.sleep(2)

    #Loop through all the Detail links on the current Search Results Page
    print("Checking search results page " + str(i))
    print(driver.current_url)
    soup = BeautifulSoup(driver.current_url, features='lxml')
    #Find all Contract detail links in the current search results page
    Details = soup.findAll('div', {'class': 'list-desc-inner'})

    for each_Contract in Details:
        #Loop through each Contract details link and scrape all the detailed 
        #Contract information page
        Details_Page = each_Contract.find('a', {'class': 'detail'}).get('href')        
        driver.get(Details_Page)
        #Scrape all the data in the Awarded Contract page
        #r = requests.get(driver.current_url)
        soup = BeautifulSoup(driver.current_url, features='lxml')

        #find a list of all the Contract Info (contained in the the 'Contact Heading'
        #class of the span element)
        Contract = soup.find_all('span', {'class': 'Contact-Heading'})
        Contract_Info = [span.get_text() for span in Contract]

        #find a list of all the Summary Contract info which is in the text of\
        #the 'list_desc_inner' class
        Sub = soup.find_all('div', {'class': 'list_desc_inner'})
        Sub_Info = [div.get_text() for div in Sub]

        #Combine the lists into a unified list and append to the Awarded table
        Combined = [Contract_Info, Sub_Info]
        Awarded.append[Combined]

        #Go back to the Search Results page (from the Detailed Contract page)
        driver.back()

    #Go to the next Search Page by clicking on the Next button at the bottom of the page
    Next_Page.click()
    #

    time.sleep(3)    

print(Awarded.Shape)

1 Ответ

0 голосов
/ 04 октября 2019

как указано, вы фактически не используете html-источник в BeautifulSoup. Итак, первое, что изменилось: soup = BeautifulSoup(driver.current_url, features='lxml') на soup = BeautifulSoup(driver.page_source, features='lxml')

Вторая проблема: у некоторых элементов нет тега <a> с class = detail. Таким образом, вы не сможете получить href от NoneType. Я добавил попробовать / исключить, чтобы пропустить, когда это произойдет (хотя я не уверен, что это даст желаемый результат). Вы также можете просто избавиться от этого класса и просто сказать Details_Page = each_Contract.find('a').get('href')

Далее, это только расширение URL, вам нужно добавить корень, поэтому: driver.get('https://www.tenders.gov.au' + Details_Page)

Я также не вижу, куда вы ссылаетесь на class = Contact-Heading.

Вы также ссылаетесь на class = 'class': 'list-desc-inner' и одну точку, затем 'class': 'list_desc_inner 'в другом. Опять же, я не вижу class = list_desc_inner

Далее. чтобы добавить список в список, вы хотите, чтобы Awarded.append(Combined), а не Awarded.append[Combined]

Я также добавил туда .strip(), чтобы очистить часть этого пробела в тексте.

В любом случае, многое нужно исправить и почистить, и я также не знаю, каким должен быть ваш ожидаемый результат. Но, надеюсь, это поможет вам начать работу.

Кроме того, как указано в комментариях, вы МОЖЕТЕ просто щелкнуть мышью на кнопке загрузки и сразу получить результаты, но, возможно, вы делаете это трудным способом на практике ...

import requests
from requests import get
from selenium import webdriver
from bs4 import BeautifulSoup
from lxml import html
import pandas as pd
#import chromedriver_binary  # Adds chromedriver binary to path

options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--incognito')
options.add_argument('--headless')
driver = webdriver.Chrome(executable_path=r"C:\chromedriver.exe")

#click the search button on Austenders to return all Awarded Contracts
import time
#define the starting point: Austenders Awarded Contracts search page
driver.get('https://www.tenders.gov.au/cn/search')
#Find the Search Button and return all search results
Search_Results = driver.find_element_by_name("SearchButton")
if 'inactive' in Search_Results.get_attribute('name'):
    print("Search Button not found")
    exit;
print('Search Button found')
Search_Results.click()    

#Pause code to prevent blocking by website
time.sleep(1)
i = 0
Awarded = []

#Move to the next search page by finding the Next button at the bottom of the page
#This code will need to be refined as the last search will be skipped currently.
while True:
    Next_Page = driver.find_element_by_class_name('next')
    if 'inactive' in Next_Page.get_attribute('class'):
        print("End of Search Results")
        exit;  
    i = i + 1
    time.sleep(2)

    #Loop through all the Detail links on the current Search Results Page
    print("Checking search results page " + str(i))
    print(driver.current_url)
    soup = BeautifulSoup(driver.page_source, features='lxml')
    #Find all Contract detail links in the current search results page
    Details = soup.findAll('div', {'class': 'list-desc-inner'})

    for each_Contract in Details:
        #Loop through each Contract details link and scrape all the detailed 
        #Contract information page
        try:
            Details_Page = each_Contract.find('a', {'class': 'detail'}).get('href')       
            driver.get('https://www.tenders.gov.au' + Details_Page)
            #Scrape all the data in the Awarded Contract page
            #r = requests.get(driver.current_url)
            soup = BeautifulSoup(driver.page_source, features='lxml')

            #find a list of all the Contract Info (contained in the the 'Contact Heading'
            #class of the span element)
            Contract = soup.find_all('span', {'class': 'Contact-Heading'})
            Contract_Info = [span.text.strip() for span in Contract]

            #find a list of all the Summary Contract info which is in the text of\
            #the 'list_desc_inner' class
            Sub = soup.find_all('div', {'class': 'list-desc-inner'})
            Sub_Info = [div.text.strip() for div in Sub]

            #Combine the lists into a unified list and append to the Awarded table
            Combined = [Contract_Info, Sub_Info]
            Awarded.append(Combined)

            #Go back to the Search Results page (from the Detailed Contract page)
            driver.back()
        except:
            continue

    #Go to the next Search Page by clicking on the Next button at the bottom of the page
    Next_Page.click()
    #

    time.sleep(3)    
driver.close()
print(Awarded.Shape)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...