私は 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§ion=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)