すべての記事をクロールクモで書かれたPythonのフレームワークScrapy 4-6分散クローラ

コマンドライン:

scrapy shell https://news.cnblogs.com/

デバッグ、URLのすべての記事ページを取得します:

>>> articles_link_xpath = '//*[@class="news_entry"]/a/@href'
>>> articles_link_selector = response.xpath(articles_link_xpath)
>>> articles_link_selector
[<Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630083/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630082/'>, <Selector xpath=
'//*[@class="news_entry"]/a/@href' data='/n/630081/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630080/'>, <Selector xpath='//*[@class="news
_entry"]/a/@href' data='/n/630079/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630078/'>, <Selector xpath='//*[@class="news_entry"]/a/@href'
 data='/n/630077/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630076/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630075/
'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630074/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630073/'>, <Selector xpa
th='//*[@class="news_entry"]/a/@href' data='/n/630072/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630071/'>, <Selector xpath='//*[@class="n
ews_entry"]/a/@href' data='/n/630070/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630069/'>, <Selector xpath='//*[@class="news_entry"]/a/@hr
ef' data='/n/630068/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630067/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/6300
66/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630065/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630064/'>, <Selector
xpath='//*[@class="news_entry"]/a/@href' data='/n/630063/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630061/'>, <Selector xpath='//*[@class
="news_entry"]/a/@href' data='/n/630062/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630060/'>, <Selector xpath='//*[@class="news_entry"]/a/
@href' data='/n/630059/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630058/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/6
30057/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630056/'>, <Selector xpath='//*[@class="news_entry"]/a/@href' data='/n/630055/'>, <Select
or xpath='//*[@class="news_entry"]/a/@href' data='/n/630054/'>]
>>> articles_link_list = articles_link_selector.extract()
>>> articles_link_list
['/n/630083/', '/n/630082/', '/n/630081/', '/n/630080/', '/n/630079/', '/n/630078/', '/n/630077/', '/n/630076/', '/n/630075/', '/n/630074/', '/n/630073/', '/n/
630072/', '/n/630071/', '/n/630070/', '/n/630069/', '/n/630068/', '/n/630067/', '/n/630066/', '/n/630065/', '/n/630064/', '/n/630063/', '/n/630061/', '/n/63006
2/', '/n/630060/', '/n/630059/', '/n/630058/', '/n/630057/', '/n/630056/', '/n/630055/', '/n/630054/']
>>> articles_link = ['https://news.cnblogs.com' + url for url in articles_link_list]
>>> articles_link
['https://news.cnblogs.com/n/630083/', 'https://news.cnblogs.com/n/630082/', 'https://news.cnblogs.com/n/630081/', 'https://news.cnblogs.com/n/630080/', 'https
://news.cnblogs.com/n/630079/', 'https://news.cnblogs.com/n/630078/', 'https://news.cnblogs.com/n/630077/', 'https://news.cnblogs.com/n/630076/', 'https://news
.cnblogs.com/n/630075/', 'https://news.cnblogs.com/n/630074/', 'https://news.cnblogs.com/n/630073/', 'https://news.cnblogs.com/n/630072/', 'https://news.cnblog
s.com/n/630071/', 'https://news.cnblogs.com/n/630070/', 'https://news.cnblogs.com/n/630069/', 'https://news.cnblogs.com/n/630068/', 'https://news.cnblogs.com/n
/630067/', 'https://news.cnblogs.com/n/630066/', 'https://news.cnblogs.com/n/630065/', 'https://news.cnblogs.com/n/630064/', 'https://news.cnblogs.com/n/630063
/', 'https://news.cnblogs.com/n/630061/', 'https://news.cnblogs.com/n/630062/', 'https://news.cnblogs.com/n/630060/', 'https://news.cnblogs.com/n/630059/', 'ht
tps://news.cnblogs.com/n/630058/', 'https://news.cnblogs.com/n/630057/', 'https://news.cnblogs.com/n/630056/', 'https://news.cnblogs.com/n/630055/', 'https://n
ews.cnblogs.com/n/630054/']

上記のコードによって、我々はフィルタの背後にある文字列は、XPathを適用していることがわかります。

/@href

あなたは、タグ内にhref属性を取得することができます。

 

start_urlsを復元するよう:

https://news.cnblogs.com/

上記のデバッグモザイクを達成するためのURLタイプのリストを生成するために使用されていますが、提供さurllibは、我々はこの方法で終了します。

ダウンロードへ記事一覧ページの記事のURL、scrapyを取得した後、解析、特定のフィールド:コードを実装解析機能、すなわち、以下の最初の関数。

from scrapy.http import Request
from urllib import parse

読むための機能を解析:

    def parse(self, response):
        """
        1. 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        2. 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        """
        # 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        articles_link = response.xpath('//*[@class="news_entry"]/a/@href').extract()
        for url in articles_link:
            yield Request(url=parse.urljoin(response.url, url), callback=self.parse_detail)
            pass

上記のコードは最初のより多目的urljoin、完全なURLにurljoinによって得られた、forループでは、スプライシング前のXPathによってURLを解析し、URLおよび要求にパラメータとして渡されたコールバック関数、および、コマンド収率、あなたはダウンロードを達成し、コールバックを解析することができます。

(再インポートするファイルの先頭に)クラスparse_detailプロセスでカプセル化された特定のフィールドを解析する前に:

    def parse_detail(self, response):
        """
        解析文章具体字段
        """
        # 标题
        title = response.xpath('//*[@id="news_title"]/a/text()').extract_first("Untitled")
        # 发布日期
        create_date = re.findall('\d{4}-\d{2}-\d{2}', response.xpath('//*[@id="news_info"]/span[2]/text()').extract_first("0000-00-00"))[0]
        # 正文
        content = response.xpath('//*[@id="news_body"]').extract_first("No content")
        # 标签
        tags = ','.join(response.xpath('//*[@id="news_more_info"]/div/a/text()').extract())
        # 来源
        source = response.xpath('//*[@id="link_source2"]/text()').extract_first('Unknown')

        pass

 

第二の機能の開発、解析、以下の機能、すなわち:、次のページのURLを取得するダウンロードするscrapy、ダウンロードが解析に完了です。

最初は、シェルのデバッグscrapyです:

>>> next_url_xpath = '//div[@class="pager"]/a[last()]/@href'
>>> next_url_selector = response.xpath(next_url_xpath)
>>> next_url_selector
[<Selector xpath='//div[@class="pager"]/a[last()]/@href' data='/n/page/2/'>]
>>> next_url = next_url_selector.extract_first()
>>> next_url
'/n/page/2/'

解析機能は、次のロジックを追加します。

        # 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        next_url = response.xpath('//div[@class="pager"]/a[not(@class)]/@href').extract_first('end')
        if next_url != 'end':
            next_url = parse.urljoin(response.url, next_url)
            yield Request(url=next_url, callback=self.parse)
        pass

上記の最後のページに与えられているが、次のラベルは、したがって、もはや最後の()を使用し、もはやありません取得されていないが、クラスの属性タグを選択していない、方法は次のとおりです。

/a[not(@class)]

全体的に、用cnblogs.py:

# -*- coding: utf-8 -*-
import scrapy
import re
from scrapy.http import Request
from urllib import parse


class CnblogsSpider(scrapy.Spider):
    name = 'cnblogs'
    allowed_domains = ['news.cnblogs.com']  # 允许的域名
    start_urls = ['https://news.cnblogs.com']  # 起始url

    def parse(self, response):
        """
        1. 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        2. 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        """
        # 获取文章列表页中的文章的url,交给scrapy下载后,进行具体字段的解析
        articles_link = response.xpath('//*[@class="news_entry"]/a/@href').extract()
        for url in articles_link:
            yield Request(url=parse.urljoin(response.url, url), callback=self.parse_detail)
            pass

        # 获取下一页的url,交给scrapy进行下载,下载完成后交给parse
        next_url = response.xpath('//div[@class="pager"]/a[not(@class)]/@href').extract_first('end')
        if next_url != 'end':
            next_url = parse.urljoin(response.url, next_url)
            yield Request(url=next_url, callback=self.parse)
        pass

    def parse_detail(self, response):
        """
        解析文章具体字段
        """
        # 标题
        title = response.xpath('//*[@id="news_title"]/a/text()').extract_first("Untitled")
        # 发布日期
        create_date = re.findall('\d{4}-\d{2}-\d{2}', response.xpath('//*[@id="news_info"]/span[2]/text()').extract_first("0000-00-00"))[0]
        # 正文
        content = response.xpath('//*[@id="news_body"]').extract_first("No content")
        # 标签
        tags = ','.join(response.xpath('//*[@id="news_more_info"]/div/a/text()').extract())
        # 来源
        source = response.xpath('//*[@id="link_source2"]/text()').extract_first('Unknown')

        pass

我々がscrapy、我々が使用urllibはや作られた要求に必要のない作業の一部を使用するので、ことに留意すべきです。私たちはコールバックメカニズムを使用することを要求が、実際には非同期です。非同期のパフォーマンスは、私たちがコンテンツを取得することで、厳密な順序の同じページではありません、着信要求URLの順序に従っていません。さらに、別のページでは、最初のフロントページの内容のほとんどは、取得するためにページの後ろのフロントページが表示されますの小さな部分を取得します。

爬虫類は、それを終了すると?実際に、コールバックは再帰的、またはサイクルの一種と見なすことができます。終了はもはや考えることが難しい問題であるときには、サイクルとしてそれを見ていないとき。

また、私たちのサイトには、クロールとほぼ3日の記事では、ビューへのログインを必要としないこと、そして、彼らは私たちは、この章で、私たちに、この問題を解決する、次の章を参照してくださいすることができます前に、記事は、ログインする必要があり三日前に発見されますコンテンツのみのほぼ3日間をクロール。だから、その後、parse_detailを書き換えます:

    def parse_detail(self, response):
        """
        解析文章具体字段
        """
        if 'account' in response.url:
            pass
        else:
            # 标题
            title = response.xpath('//*[@id="news_title"]/a/text()').extract_first("Untitled")
            # 发布日期
            create_date = re.findall('\d{4}-\d{2}-\d{2}', response.xpath('//*[@id="news_info"]/span[2]/text()').extract_first("0000-00-00"))[0]
            # 正文
            content = response.xpath('//*[@id="news_body"]').extract_first("No content")
            # 标签
            tags = ','.join(response.xpath('//*[@id="news_more_info"]/div/a/text()').extract())
            # 来源
            source = response.xpath('//*[@id="link_source2"]/text()').extract_first('Unknown')

            pass

        pass

 

公開された101元の記事 ウォン称賛26 ビュー10000 +

おすすめ

転載: blog.csdn.net/liujh_990807/article/details/100046015