Python クローラーを最初から始めるためのクイックガイド

阿神
リリース: 2017-01-23 16:45:24
オリジナル
1224 人が閲覧しました

まえがき

この記事の主な内容: フォーラムの投稿タイトルと投稿コンテンツをクロールできる最も単純なクローラーを最短時間で作成します。

この記事の対象者: クローラーについて書いたことのない初心者。


はじめに

0. 準備する必要があるもの: Python、scrapy、IDE、または任意のテキスト編集ツール。

1. 技術部門が検討し、あなたがクローラーを書くことを決定しました。

任意に作業ディレクトリを作成し、コマンドラインを使用してプロジェクトを作成します。プロジェクト名はmiaoです。これは好きな名前に置き換えることができます。

scrapy startproject miao
ログイン後にコピー

すると、scrapyによって作成された以下のディレクトリ構造が得られます


クローラースクリプトとして、miao.pyなどのpythonファイルをspidersフォルダー内に作成します。内容は以下の通りです。 Python クローラーを最初から始めるためのクイックガイド

import scrapy
class NgaSpider(scrapy.Spider):
    name = "NgaSpider"
    host = "http://bbs.ngacn.cc/"
    # start_urls是我们准备爬的初始页
    start_urls = [
        "http://bbs.ngacn.cc/thread.php?fid=406",
    ]
    # 这个是解析函数,如果不特别指明的话,scrapy抓回来的页面会由这个函数进行解析。
    # 对页面的处理和分析工作都在此进行,这个示例里我们只是简单地把页面内容打印出来。
    def parse(self, response):
        print response.body
ログイン後にコピー


2. 試してみませんか?

コマンドラインを使用する場合は、次のようになります:

cd miao
scrapy crawl NgaSpider
ログイン後にコピー

クローラーが星間領域の最初のページを出力したことがわかります。もちろん、何も処理されていないため、HTML タグとjs スクリプトを出力します。


分析

次に、キャプチャしたページを分析し、この HTML と JS の山からこのページの投稿タイトルを抽出する必要があります。実際、ページの解析は面倒な作業なので、ここでは xpath のみを紹介します。

0. 魔法の xpath を試してみてはいかがでしょうか

先ほど取得したものを確認するか、Chrome ブラウザでページを手動で開き、F12 キーを押してページ構造を確認してください。各タイトルは実際にはこのような html タグで囲まれています。例:

<a href=&#39;/read.php?tid=10803874&#39; id=&#39;t_tt1_33&#39; class=&#39;topic&#39;>[合作模式] 合作模式修改设想</a>
ログイン後にコピー

href がこの投稿のアドレスであり (もちろんフォーラムのアドレスを先頭に入力する必要があります)、このタグで囲まれたコンテンツが投稿のタイトルであることがわかります。

そこで、xpathの絶対配置法を使ってclass='topic'の部分を抽出しました。


1. xpath の効果を見てください

先頭に引用符を追加します:

from scrapy import Selector
ログイン後にコピー

解析関数を次のように変更します:

 def parse(self, response):
        selector = Selector(response)
        # 在此,xpath会将所有class=topic的标签提取出来,当然这是个list
        # 这个list里的每一个元素都是我们要找的html标签
        content_list = selector.xpath("//*[@class=&#39;topic&#39;]")
        # 遍历这个list,处理每一个标签
        for content in content_list:
            # 此处解析标签,提取出我们需要的帖子标题。
            topic = content.xpath(&#39;string(.)&#39;).extract_first()
            print topic
            # 此处提取出帖子的url地址。
            url = self.host + content.xpath(&#39;@href&#39;).extract_first()
            print url
ログイン後にコピー

もう一度実行すると、すべての投稿のタイトルの出力が表示されます。フォーラムの星間エリアの最初のページと URL。


再帰

次に、各投稿のコンテンツをキャプチャする必要があります。ここではPythonのyieldを使用する必要があります。

yield Request(url=url, callback=self.parse_topic)
ログイン後にコピー

ここでは、scrapy にこの URL をクロールし、指定された parse_topic 関数を使用してクロールされたページを解析するように指示します。

この時点で、投稿の内容を分析するための新しい関数を定義する必要があります。

完全なコードは次のとおりです:

import scrapy
from scrapy import Selector
from scrapy import Request
class NgaSpider(scrapy.Spider):
    name = "NgaSpider"
    host = "http://bbs.ngacn.cc/"
    # 这个例子中只指定了一个页面作为爬取的起始url
    # 当然从数据库或者文件或者什么其他地方读取起始url也是可以的
    start_urls = [
        "http://bbs.ngacn.cc/thread.php?fid=406",
    ]

    # 爬虫的入口,可以在此进行一些初始化工作,比如从某个文件或者数据库读入起始url
    def start_requests(self):
        for url in self.start_urls:
            # 此处将起始url加入scrapy的待爬取队列,并指定解析函数
            # scrapy会自行调度,并访问该url然后把内容拿回来
            yield Request(url=url, callback=self.parse_page)

    # 版面解析函数,解析一个版面上的帖子的标题和地址
    def parse_page(self, response):
        selector = Selector(response)
        content_list = selector.xpath("//*[@class=&#39;topic&#39;]")
        for content in content_list:
            topic = content.xpath(&#39;string(.)&#39;).extract_first()
            print topic
            url = self.host + content.xpath(&#39;@href&#39;).extract_first()
            print url
            # 此处,将解析出的帖子地址加入待爬取队列,并指定解析函数
            yield Request(url=url, callback=self.parse_topic)
         # 可以在此处解析翻页信息,从而实现爬取版区的多个页面

    # 帖子的解析函数,解析一个帖子的每一楼的内容
    def parse_topic(self, response):
        selector = Selector(response)
        content_list = selector.xpath("//*[@class=&#39;postcontent ubbcode&#39;]")
        for content in content_list:
            content = content.xpath(&#39;string(.)&#39;).extract_first()
            print content
        # 可以在此处解析翻页信息,从而实现爬取帖子的多个页面
ログイン後にコピー

これまでのところ、このクローラーはフォーラムの最初のページにあるすべての投稿のタイトルをクロールし、各投稿の最初のページの各フロアのコンテンツをクロールできます。複数のページをクロールする原理は同じですが、ページの URL アドレスの解析、終了条件の設定、および対応するページ解析関数の指定に注意してください。


パイプライン—パイプライン

ここでは、キャプチャおよび解析されたコンテンツの処理を示します。これらのコンテンツは、パイプラインを通じてローカル ファイルやデータベースに書き込むことができます。

0. アイテムを定義する

miao フォルダーに items.py ファイルを作成します。

from scrapy import Item, Field
class TopicItem(Item):
    url = Field()
    title = Field() 
    author = Field()  
    
class ContentItem(Item):
    url = Field() 
    content = Field()
    author = Field()
ログイン後にコピー

ここでは、クロールの結果を記述する 2 つの単純なクラスを定義します。

1. 処理メソッドを記述します

以前に Scrapy が自動生成されているはずの Pipelines.py ファイルを見つけます。

ここで処理メソッドを構築できます。

class FilePipeline(object):

    ## 爬虫的分析结果都会由scrapy交给此函数处理
    def process_item(self, item, spider):
        if isinstance(item, TopicItem):            ## 在此可进行文件写入、数据库写入等操作
            pass
        if isinstance(item, ContentItem):            ## 在此可进行文件写入、数据库写入等操作
            pass
        ## ... 
        return item
ログイン後にコピー

2. クローラーでこの処理メソッドを呼び出します

このメソッドを呼び出すには、クローラー内で呼び出すだけです。たとえば、元のコンテンツ処理関数を次のように変更できます。

    def parse_topic(self, response):
        selector = Selector(response)
        content_list = selector.xpath("//*[@class=&#39;postcontent ubbcode&#39;]")        for content in content_list:
            content = content.xpath(&#39;string(.)&#39;).extract_first()            ## 以上是原内容
            ## 创建个ContentItem对象把我们爬取的东西放进去
            item = ContentItem()
            item["url"] = response.url
            item["content"] = content
            item["author"] = "" ## 略
            ## 这样调用就可以了
            ## scrapy会把这个item交给我们刚刚写的FilePipeline来处理
            yield item
ログイン後にコピー

3. 設定ファイルでこのパイプラインを指定します。 py ファイルを開き、その中で見つけます

ITEM_PIPELINES = {            &#39;miao.pipelines.FilePipeline&#39;: 400,
        }
ログイン後にコピー

を追加してクローラーで呼び出す

yield item
ログイン後にコピー

はこの FilePipeline によって処理されます。次の数字 400 は優先度を表します。

ここで複数のパイプラインを設定できます。Scrapy は優先度に従って順番にアイテムを各アイテムに渡し、各処理の結果は次のパイプラインに渡されて処理されます。

次のように複数のパイプラインを構成できます:

ITEM_PIPELINES = {
            &#39;miao.pipelines.Pipeline00&#39;: 400,
            &#39;miao.pipelines.Pipeline01&#39;: 401,
            &#39;miao.pipelines.Pipeline02&#39;: 402,
            &#39;miao.pipelines.Pipeline03&#39;: 403,
            ## ...
        }
ログイン後にコピー



ミドルウェア - ミドルウェア


ミドルウェアを通じて、UA、プロキシ、ログインの一般的に使用される設定など、リクエスト情報にいくつかの変更を加えることができます。情報などはミドルウェアを通じて設定できます。 0. Middleware

の設定は、Setting.pyに

DOWNLOADER_MIDDLEWARES = {
            "miao.middleware.UserAgentMiddleware": 401,
            "miao.middleware.ProxyMiddleware": 402,
        }
ログイン後にコピー

1のように、UAを確認するためにWebサイトの名前を追加します。

某些网站不带UA是不让访问的。在miao文件夹下面建立一个middleware.py

import random


agents = [
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5",
    "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/532.9 (KHTML, like Gecko) Chrome/5.0.310.0 Safari/532.9",
    "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.514.0 Safari/534.7",
    "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/9.0.601.0 Safari/534.14",
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.14 (KHTML, like Gecko) Chrome/10.0.601.0 Safari/534.14",
    "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.20 (KHTML, like Gecko) Chrome/11.0.672.2 Safari/534.20",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.27 (KHTML, like Gecko) Chrome/12.0.712.0 Safari/534.27",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.24 Safari/535.1",
]


class UserAgentMiddleware(object): 

    def process_request(self, request, spider):
        agent = random.choice(agents)
        request.headers["User-Agent"] = agent
ログイン後にコピー

这里就是一个简单的随机更换UA的中间件,agents的内容可以自行扩充。

2.破网站封IP,我要用代理

比如本地127.0.0.1开启了一个8123端口的代理,同样可以通过中间件配置让爬虫通过这个代理来对目标网站进行爬取。同样在middleware.py中加入:

class ProxyMiddleware(object):
    def process_request(self, request, spider): 
        # 此处填写你自己的代理
        # 如果是买的代理的话可以去用API获取代理列表然后随机选择一个
        proxy = "http://127.0.0.1:8123"
        request.meta["proxy"] = proxy
ログイン後にコピー

很多网站会对访问次数进行限制,如果访问频率过高的话会临时禁封IP。如果需要的话可以从网上购买IP,一般服务商会提供一个API来获取当前可用的IP池,选一个填到这里就好。


一些常用配置

在settings.py中的一些常用配置

# 间隔时间,单位秒。指明scrapy每两个请求之间的间隔。
DOWNLOAD_DELAY = 5 

# 当访问异常时是否进行重试
RETRY_ENABLED = True 
# 当遇到以下http状态码时进行重试
RETRY_HTTP_CODES = [500, 502, 503, 504, 400, 403, 404, 408]
# 重试次数
RETRY_TIMES = 5

# Pipeline的并发数。同时最多可以有多少个Pipeline来处理item
CONCURRENT_ITEMS = 200
# 并发请求的最大数
CONCURRENT_REQUESTS = 100
# 对一个网站的最大并发数
CONCURRENT_REQUESTS_PER_DOMAIN = 50
# 对一个IP的最大并发数
CONCURRENT_REQUESTS_PER_IP = 50
ログイン後にコピー
我就是要用Pycharm

如果非要用Pycharm作为开发调试工具的话可以在运行配置里进行如下配置:
Configuration页面:
Script填你的scrapy的cmdline.py路径,比如我的是

/usr/local/lib/python2.7/dist-packages/scrapy/cmdline.py
ログイン後にコピー

然后在Scrpit parameters中填爬虫的名字,本例中即为:

crawl NgaSpider
ログイン後にコピー

最后是Working diretory,找到你的settings.py文件,填这个文件所在的目录。
示例:

Python クローラーを最初から始めるためのクイックガイド

按小绿箭头就可以愉快地调试了。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!