ksk_y
@ksk_y

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

for文を使うとtextが抽出できなくなる

解決したいこと

Pythonでスクレイピングの練習をしているのですが、
以下エラーが発生してしまいます。

独学を初めて3日目で、早くも挫折しそうです...
みなさまのご知見をお貸しいただけますと幸いです。

発生している問題・エラー

for文を回さない際はtextが抽出できるのですが、for文を用いると以下エラーが発生します

出ているエラーメッセージを入力
'NoneType' object has no attribute 'text'

該当するソースコード

for job in jobs:
    company_name = job.find('span',class_='companyName').text
    title = job.find('a',class_='catch').text
    salary = job.find('span',class_='data data--income').text
    area = job.find('span',class_='data data--area').text

    d = {
    '会社名': company_name,
    '求人名': title,
    '職種' :job_type,
    '年収':salary,
    }

    d_list.append(d)

    d_list

    [{'会社名': <span class="companyName">株式会社エイトノット</span>,
  '求人名': <a class="catch" href="https://en-ambi.com/job/j-8623923/" itemprop="title">ゼロからの仕組み作りに挑戦できる人事担当募集</a>,
  '職種': <div class="jobType">人事採用教育など</div>,
  '年収': <span class="data data--income">450万円  749万円</span>},

自分で試したこと

for分を外すと、問題なくtextのみ抽出できます。

0

3Answer

部分的なコードのようですが、

  • スクレイピングのライブラリはなんですか?
  • jobsはどういう定義なんですか?
  • jobsはそのライブラリを継承しているようなものでしょうか
2Like

Comments

  1. @ksk_y

    Questioner

    ご質問ありがとうございます、以下コード全文でございます。

    from bs4 import BeautifulSoup
    import requests
    
    url = "https://en-ambi.com/search/?jobtype=1112010&jobmerit=60&freeword=%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%80%80%E3%83%99%E3%83%B3%E3%83%81%E3%83%A3%E3%83%BC%22&fTab=all&isStatic=&BASE_URL_=&uri_segment=&per_page={}"
    target_url = url.format(1)
    res = requests.get(target_url)
    soup = BeautifulSoup(res.text)
    d_list=[]
    jobs = soup.find_all('div',class_='base')
    for job in jobs:
        company_name = job.find('span',class_='companyName').text
        title = job.find('a',class_='catch')
        job_type = job.find('div',class_='jobType')
        salary = job.find('span',class_='data data--income')
        area = job.find('span',class_='data data--area')
    
        d = {
        '会社名': company_name,
        '求人名': title,
        '職種' :job_type,
        '年収':salary,
        }
    
        d_list.append(d)
    
  2. @shiracamus さんがご指摘されているように、ループの中で抽出対象のタグがないものがあるかですね
    実際にどのようなものが抽出されるか確認された方がいいかと思います。

    jobs = soup.find_all('div',class_='base')

    image.png

書籍とかネットの記事の影響でしょうか気軽にスクレイピングを始める人が多いようですが、スクレイピングはサイトの管理者に許可を得ているとか、規約に従って専用の API にアクセスしているとかでなければ、迷惑行為になるかもしれないということは認識してますか?

クローラーを作って某図書館サイトにアクセスしたら業務妨害とかで逮捕された事例もありますので、甘く見ない方がいいと思います。

逮捕までいかなくても、被害が深刻な場合は損害賠償の訴訟を受けるかもしれません。

訴訟までいかなくても、アクセス遮断なら Web サーバーの設定で管理者だけの判断で容易に可能なので、多分に可能性はあると思います。帯域ごと遮断され、多数の利用者が巻き添えを喰らうことになるかもしれません。

回答するのは迷惑行為の手助けをすることになるかもしれないということで、上記の辺りに問題がないことを示してもらえないと回答は得にくいと思います。

2Like

job.find('span',class_='companyName') などで None が返るjobがあるのでは?

同様な処理を書いてみたら同様なエラーになりました。

sample.py
class Text:
    def __init__(self, text):
        self.text = text

class Job:
    def __init__(self, items):
        self.items = items
    def find(self, key):
        return self.items.get(key)

jobs = [
    Job({'companyName': Text("A社")}),
    Job({}),  # companyNameなし
    Job({'companyName': Text("B社")}),
]

for job in jobs:
    company_name = job.find('companyName').text
    print(company_name)
実行結果
A社
Traceback (most recent call last):
  File "/home/qiita/sample.py", line 18, in <module>
    company_name = job.find('companyName').text
AttributeError: 'NoneType' object has no attribute 'text'
2Like

Comments

  1. @ksk_y

    Questioner

    アドバイス頂きありがとうございます。
    自分では気付かなかった簡単ですので、一度調べてみます。

Your answer might help someone💌