2

私は C/C++ プログラマーであり、プロットとテキスト処理の作成において Python の経験が限られています。私は現在、個人データ分析プロジェクトに取り組んでおり、Scrapy を使用してフォーラム内のすべてのスレッドとユーザー情報をクロールしています。

最初にログインすることを目的とした初期コードをまとめました。次に、サブフォーラムのインデックス作成ページから開始し、次のことを行います。

1) 「トピック」を含むすべてのスレッド リンクを抽出する

2) 今のところページをファイルに保存します (プロセス全体が機能したらアイテム情報を抽出します)

3) タグ class=next を持つ次のページ リンクを見つけ、次のページに移動して 1) と 2) を繰り返します。

スレッドごとに、すべての返信投稿を含むすべてのページを確認する必要があることはわかっていますが、現在のコードが正しく機能するようになったら、それを行う予定です。

ただし、私の現在のコードは、開始 URL のすべてのスレッドのみを抽出してから停止します。数時間検索しましたが、これに対する解決策は見つかりませんでした。だから私はここで私の質問をし、Scrapy の経験を持つ誰かがここで私を助けてくれることを願っています. 出力などの他の情報が必要な場合は、お知らせください。ありがとう!

Paul の返信については、コードを更新しました。リンク エクストラクタに問題があるため、修正する必要があります。それ以外は、ルールは正常に機能するようになりました。ポールの助けに再び感謝します。

これが私の現在のスパイダーコードです:

from scrapy.contrib.spiders import CrawlSpider
from scrapy.http import Request, FormRequest
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.contrib.spiders import Rule
from scrapy.selector import Selector

class ZhuaSpider(CrawlSpider):
    name = 'zhuaspider'
    allowed_domains = ['depressionforums.org']
    login_page = 'http://www.domain.com/forums/index.php?app=core&module=global&section=login'
    start_urls = ['http://www.depressionforums.org/forums/forum/12-depression-central/']

    rules = (Rule(SgmlLinkExtractor(restrict_xpaths=('//li[@class="next"]'), unique=True),
                           callback='parse_links',
                           follow=True),
            )

    def start_requests(self):
        """called before crawling starts. Try to login"""
        yield Request(
                url=self.login_page,
                callback=self.login,
                dont_filter=True)

    def login(self, response):
        """Generate a login request."""
        return FormRequest.from_response(response,
                formdata={'ips_username': 'myuid', 'ips_password': 'mypwd'},
                callback=self.check_login_response)

    def check_login_response(self, response):
        """Check the response returned by a login request to see if we are successfully logged in."""
        if "Username or password incorrect" in response.body:
            self.log("Login failed.")
        else:
            self.log("Successfully logged in. Let's start crawling!")
            # Now the crawling can begin.
            for url in self.start_urls:
                # explicitly ask Scrapy to run the responses through rules
                yield Request(url, callback=self.parse)

    def parse_links(self, response):
        hxs = Selector(response)
        links = hxs.xpath('//a[contains(@href, "topic")]')
        for link in links:
            title = ''.join(link.xpath('./@title').extract())
            url = ''.join(link.xpath('./@href').extract())
            meta={'title':title,}
            yield Request(url, callback = self.parse_posts, meta=meta,)

    #If I add this line it will only crawl the starting url,
    #otherwise it still won't apply the rule and crawls nothing.
    parse_start_url = parse_links

    def parse_posts(self, response):
        filename = 'download/'+ response.url.split("/")[-2]
        open(filename, 'wb').write(response.body)
4

1 に答える 1

2

を利用するには、内部メソッドで処理する必要がありますCrawlSpiderRulesRequestsparse()

これは、コールバックを明示的に設定するcallback=self.parseか、設定しないことで実行できます。

start_urls = ['http://www.depressionforums.org/forums/forum/12-depression-central/']

rules = (
    Rule(SgmlLinkExtractor(restrict_xpaths=('//li[@class="next"]'), unique=True),
                           callback='parse_links',
                           follow=True),
)

...

def check_login_response(self, response):
    """Check the response returned by a login request to see if we are successfully logged in."""
    if "Username or password incorrect" in response.body:
        self.log("Login failed.")
    else:
        self.log("Successfully logged in. Let's start crawling!")
        # Now the crawling can begin.
        for url in self.start_urls:
            # explicitly ask Scrapy to run the responses through rules
            yield Request(url, callback=self.parse)

//li[@class="next"]次に、それだけで、クロールされ、解析されたセクション内のリンクのページが表示されるはずparse_links()です... start_urls自体を期待してください。

parse_linksstart_urls を通過するには、特別なparse_start_url属性を定義する必要があります。

あなたはこれを行うことができます:

def parse_links(self, response):
    hxs = Selector(response)
    links = hxs.xpath('//a[contains(@href, "topic")]')
    for link in links:
        title = ''.join(link.xpath('./@title').extract())
        url = ''.join(link.xpath('./@href').extract())
        meta={'title':title,}
        yield Request(url, callback = self.parse_posts, meta=meta,)

parse_start_url = parse_links
于 2014-05-28T08:00:18.130 に答える