Как исправить «AttributeError: объект« NoneType »не имеет атрибута« текст »» для <span> - PullRequest
0 голосов
/ 02 июля 2019

Я пробую веб-скребок с Python 3.7 и BeautifulSoup.Я извлек данные для «posting-name», «small-category-label-post-category-by-location» по следующему html, но могуНе извлекайте «метку малой категории для публикации по категориям» (либо полностью занятую, либо нет), в то время как структура html выглядит так же, как и другие:

<div class="posting" data-qa-posting-id="13f9db2f-7a80-4b50-9a61-005ad322ea2d">
   <div class="posting-apply" data-qa="btn-apply">
      <a href="https://jobs.lever.co/twitch/13f9db2f-7a80-4b50-9a61-005ad322ea2d" class="posting-btn-submit template-btn-submit hex-color">Apply</a>
   </div>
   <a class="posting-title" href="https://jobs.lever.co/twitch/13f9db2f-7a80-4b50-9a61-005ad322ea2d">
      <h5 data-qa="posting-name">Account Director - DACH</h5>
      <div class="posting-categories">
         <span href="#" class="sort-by-location posting-category small-category-label">Hamburg, Germany</span>
         <span href="#" class="sort-by-team posting-category small-category-label">Business Operations &amp; Go-To-Market – Advertising</span>
         <span href="#" class="sort-by-commitment posting-category small-category-label">Full-time</span>
      </div>
   </a>
</div>

Я пытался создатьотдельный суп для «категорий публикаций», но не сработал.

import requests
from bs4 import BeautifulSoup
from csv import writer

response = requests.get('https://jobs.lever.co/twitch')

soup = BeautifulSoup(response.text, 'html.parser')

posts = soup.findAll('div', {'class':'posting'})

with open('twitch.csv', 'w') as csv_file:
    csv_writer = writer(csv_file)

    headers = ['Position', 'Link', 'Location', 'Team', 'Commitment']

    csv_writer.writerow(headers)

    for post in posts:
        position = post.find('h5',{'data-qa':'posting-name'}).text
        link = post.find('a')['href']
        location = post.find('span',{'class':'sort-by-location posting-category small-category-label'}).text
        team = post.find('span',{'class':'sort-by-team posting-category small-category-label'}).text
        commitment = post.find('span',{'class':'sort-by-commitment posting-category small-category-label'}).text
        csv_writer.writerow([position, link, location, team, commitment])

Ожидаемый результат в csv вернет название позиции, ссылку (URL), местоположение, команду и обязательство.

На данный момент я получаю следующую ошибку:

 commitment = post.find('span',{'class':'sort-by-commitment posting-category small-category-label'}).text
AttributeError: 'NoneType' object has no attribute 'text'

* Редактировать: в наборе данных отсутствует эта последняя строка, и я не могу понять, почему:

<a class="posting-title" href="https://jobs.lever.co/twitch/c8cc56e7-75f6-4cac-9983-e0769db9dd2e">
   <h5 data-qa="posting-name">Applied Scientist Intern</h5>
   <div class="posting-categories">
      <span href="#" class="sort-by-location posting-category small-category-label">San Francisco, CA</span>
      <span href="#" class="sort-by-team posting-category small-category-label">University (Internships) – Engineering</span>
      <span href="#" class="sort-by-commitment posting-category small-category-label">Intern</span>

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Вы также можете использовать try except:

for post in posts:
    try:
        position = post.find('h5',{'data-qa':'posting-name'}).text
        link = post.find('a')['href']
        location = post.find('span',{'class':'sort-by-location posting-category small-category-label'}).text
        team = post.find('span',{'class':'sort-by-team posting-category small-category-label'}).text
        commitment = post.find('span',{'class':'sort-by-commitment posting-category small-category-label'}).text
        csv_writer.writerow([position, link, location, team, commitment])
    except:
        continue
0 голосов
/ 02 июля 2019

Если вы проверяете html, в некоторых случаях отсутствует commitment, в этом случае вы должны предоставить условие if. Попробуйте сейчас приведенный ниже код.

for post in posts:
        position = post.find('h5',{'data-qa':'posting-name'}).text
        link = post.find('a')['href']
        location = post.find('span',{'class':'sort-by-location posting-category small-category-label'}).text
        team = post.find('span',{'class':'sort-by-team posting-category small-category-label'}).text
        if post.find('span',{'class':'sort-by-commitment posting-category small-category-label'}):
            commitment = post.find('span',{'class':'sort-by-commitment posting-category small-category-label'}).text
            csv_writer.writerow([position, link, location, team, commitment])

Я бы скорее предложил вам использовать css selector вместо find.

import requests
from bs4 import BeautifulSoup
from csv import writer

response = requests.get('https://jobs.lever.co/twitch')
soup = BeautifulSoup(response.text, 'html.parser')
posts = soup.select('div.posting')

with open('twitch.csv', 'w') as csv_file:
    csv_writer = writer(csv_file)

    headers = ['Position', 'Link', 'Location', 'Team', 'Commitment']

    csv_writer.writerow(headers)


    for post in posts:
        position = post.select_one('h5[data-qa="posting-name"]').text
        link = post.select_one('a')['href']
        location = post.select_one('.sort-by-location').text
        team = post.select_one('.sort-by-team').text
        if post.select_one('.sort-by-commitment'):
         commitment = post.select_one('.sort-by-commitment').text
        csv_writer.writerow([position, link, location, team, commitment])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...