質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • Python

    12249questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • スクレイピング

    492questions

    スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

ScrapyによるWebスクレイピングがうまくいかない

受付中

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 685

ster

score 0

 前提・実現したいこと

python クローリング&スクレイピングという本でScrapyの使い方を勉強しています。掲載したコードはYahoo!ニュースのトップページに表示されているトピックス一覧から個別のトピックスへのリンクをたどり、トピックスのタイトルと本文を抽出するためのものです。

このコードをscrapy crawl news -o news.csvで実行しCSVファイルを作成すると、トピックスのタイトルと本文の一覧を表形式で見ることができました。

私はこの方法を参考にして他のWEBサイトから個別ページのタイトル、本文、URLを全て抜き出しCSVファイルに保存したいと考えています。その目的を実現させるためにいくつかの方法を試したのですがうまくいきません。何がいけいないのか教えてもらえると助かります。

また、同じことをScrapy以外でするとしたらどのような方法があるでしょうか。

 発生している問題・エラーメッセージ

書籍のサンプルコードを修正してCSVに保存したが、ファイルを開くとデータが入っていなかった。

 該当のソースコード

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class MyprojectItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass


class Headline(scrapy.Item):
    """
    ニュースのヘッドラインを表すItem。
    """

    title = scrapy.Field()
    body = scrapy.Field()
import scrapy

from myproject.items import Headline  # ItemのHeadlineクラスをインポート。


class NewsSpider(scrapy.Spider):
    name = "news"  # Spiderの名前。
    # クロール対象とするドメインのリスト。
    allowed_domains = ["news.yahoo.co.jp"]
    # クロールを開始するURLのリスト。
    start_urls = (
        'http://news.yahoo.co.jp/',
    )

    def parse(self, response):
        """
        トップページのトピックス一覧から個々のトピックスへのリンクを抜き出してたどる。
        """
        for url in response.css('ul.topics a::attr("href")').re(r'/pickup/\d+$'):
            yield scrapy.Request(response.urljoin(url), self.parse_topics)

    def parse_topics(self, response):
        """
        トピックスのページからタイトルと本文を抜き出す。
        """
        item = Headline()  # Headlineオブジェクトを作成。
        item['title'] = response.css('.newsTitle ::text').extract_first()  # タイトル
        item['body'] = response.css('.hbody').xpath('string()').extract_first()  # 本文
        yield item  # Itemをyieldして、データを抽出する。

 試したこと

  • class Headline(scrapy.Item):内にurl= scrapy.Field()を追加。
  • class NewsSpider(scrapy.Spider):内のallowed_domains = ["news.yahoo.co.jp"]とstart_urls = ('http://news.yahoo.co.jp/',)に記述したURLを取得したいサイトのURLに変更。
  • def parse_topics(self, response):内のitem['title'] =rsponse.css('.newsTitle ::text').extract_first()の.newsTitleをChromeの開発ツールで調べたclass名entry-titleに変更。
  • item['body'] = response.css('.hbody').xpath('string()').extract_first()の.hbodyをChromeの開発ツールで調べたclass名entry-contentに変更。  
  • item['body']の下にitem['URL'] = response.urlを追加。
  • 保存したコードをscrapy crawl news -o news.csvで実行

 補足情報(FW/ツールのバージョンなど)

特になし

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

0

Scrapy はわからないですが、スクレイピングだと BeautifulSoup が有名ですね。以下のようにかけます。

import csv
import urllib

from bs4 import BeautifulSoup

url = 'https://news.yahoo.co.jp/'  # 取得先URL
html = urllib.request.urlopen(url).read()
soup = BeautifulSoup(html, 'html.parser')

topics = []
for a_elem in soup.select('ul.topics a'):
    topic_url = urllib.parse.urljoin('https://news.yahoo.co.jp/', a_elem.get('href'))

    # 「もっと見る」、「全カテゴリのトピックス一覧」を無視
    if 'pickup' in topic_url:
        # <span class="icPhoto">写真</span>, <span class="icNew">new</span> を削除
        [elem.extract() for elem in a_elem.findAll('span')]
        topic_title = a_elem.text
        topics.append([topic_title, topic_url])

# CSV に出力する。
with open('topics.csv', 'w', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['タイトル', 'URL'])  # ヘッダーを書き込む。
    writer.writerows(topics)  # データを書き込む。
タイトル,URL
日経平均 一時900円超安,https://news.yahoo.co.jp/pickup/6299690
米軍ヘリ炎上1年 進まぬ捜査,https://news.yahoo.co.jp/pickup/6299666
米ハリケーン 大災害の恐れ,https://news.yahoo.co.jp/pickup/6299677
韓国外相 制裁巡る発言を謝罪,https://news.yahoo.co.jp/pickup/6299674
コンビニバイト訴える理不尽,https://news.yahoo.co.jp/pickup/6299686
金本監督 今季限りで辞任,https://news.yahoo.co.jp/pickup/6299695
吉田輝星の迷い 消した学校長,https://news.yahoo.co.jp/pickup/6299685
ケンタロウ奇跡の回復 笑顔も,https://news.yahoo.co.jp/pickup/6299678

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

同じ質問でしたのでこちらにも
https://teratail.com/questions/160826

cssセレクタが変更されているようです

変更前
ul.topics

変更後
ul.toptopics_list

    def parse(self, response):
        for url in response.css('ul.toptopics_list a::attr("href")').re(r'/pickup/\d+$'):
            yield scrapy.Request(response.urljoin(url), self.parse_topics)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-1

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Python

    12249questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • スクレイピング

    492questions

    スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。