ホームページ >バックエンド開発 >Python チュートリアル >Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

高洛峰
高洛峰オリジナル
2016-11-07 16:43:351935ブラウズ

背景:

PySpider: 強力な WebUI を備えた中国人によって書かれた強力な Web クローラー システム。 Python 言語で書かれており、分散アーキテクチャを持ち、複数のデータベース バックエンドをサポートしており、強力な WebUI はスクリプト エディター、タスク モニター、プロジェクト マネージャー、および結果ビューアーをサポートしています。オンラインの例: http://demo.pyspider.org/

公式ドキュメント: http://docs.pyspider.org/en/l...

Github: https://github.com/binux/pysp. ..

この記事のクローラー コードの Github アドレス: https://github.com/zhisheng17...

さらに興味深い記事は、WeChat 公開アカウント: Yuanblog で読むことができます。フォロー歓迎です。

ここまで言って、本文に入りましょう!

前提条件:

Pyspider と MySQL-python が既にインストールされています (データを保存)

まだインストールしていない場合は、私の前の記事 この記事を読めば、寄り道を防ぐことができます。

Pyspider フレームワークを学習するときに経験したいくつかの落とし穴

HTTP 599: SSL 証明書の問題: ローカル発行者の証明書エラーを取得できない

遭遇したいくつかのエラー:

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

まず第一に、このクローラーの目標: Pyspider を使用する このフレームワークは、V2EX Web サイト上の投稿内の質問とコンテンツをクロールし、クロールされたデータをローカルに保存します。

V2EX のほとんどの投稿は閲覧するためにログインする必要がありません。もちろん、一部の投稿は閲覧するためにログインする必要があります。 (クロール中にエラーが頻繁に発生し、具体的な理由を確認したところ、その投稿を表示するにはログインする必要があることが判明したため) ですので、もちろん、Cookie を使用する必要はないと思います。ログインする必要がありますが、ローカルの方法はログイン後に Cookie を追加するだけです。

https://www.v2ex.com/ をスキャンしたところ、すべての投稿を含めることができるリストは存在しないことがわかりました。次善の策として、カテゴリの下にあるすべてのタグ リスト ページを取得してリストを横断するしかありません。すべての投稿: https://www.v2ex.com/?tab=tech 次に https://www.v2ex.com/go/progr... 最後に、各投稿の詳細なアドレスは (例): https: //www.v2ex.com/t/314683...

プロジェクトを作成します

pyspiderダッシュボードの右下隅にある「作成」ボタンをクリックします

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

self.crawlのURLを置き換えますon_start 関数:

@every(minutes=24 * 60) 
    def on_start(self): 
        self.crawl('https://www.v2ex.com/', callback=self.index_page, validate_cert=False)

self.crawl は、指定されたページをクロールし、コールバック関数を使用して結果を解析するように pyspider に指示します。

@every) 修飾子。最新の投稿をキャプチャできるように、on_start が 1 日に 1 回実行されることを示します。

validate_cert=False はこのようにする必要があります。そうでない場合は、HTTP 599: SSL 証明書の問題: ローカル発行者の証明書を取得できないエラーが報告されます

ホームページ:

緑色の実行をクリックして実行すると、画面上に赤い 1 が表示されます以下のパネルに切り替えて、緑色の再生ボタンをクリックします。

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

この問題は、2 番目のスクリーンショットの最初に表示されました。解決策については、以前に書かれた記事を参照してください。その後、問題は発生しなくなります。 。

タブ リスト ページ:

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

タブ リスト ページでは、すべてのトピック リスト ページの URL を抽出する必要があります。サンプル ハンドラーが非常に大きな URL を抽出したことに気付いたかもしれません

コード:

@config(age=10 * 24 * 60 * 60) 
    def index_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/?tab="]').items(): 
            self.crawl(each.attr.href, callback=self.tab_page, validate_cert=False)

投稿リスト ページとタブ リスト ページの長さが同じではないため、ここで新しいコールバックが self.tab_page として作成されます

@ config (age=10 24 60 * 60) これは、ページが 10 日以内に有効であり、更新もクロールも再度行われないと考えられることを意味します

リストページ:

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

コード:

@config(age=10 * 24 * 60 * 60) 
 
def tab_page(self, response): 
 
for each in response.doc('a[href^="https://www.v2ex.com/go/"]').items(): 
 
self.crawl(each.attr.href, callback=self.board_page, validate_cert=False)

投稿詳細ページ(T):

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

結果にはいくつかの返信が含まれていることがわかりますが、これらは不要なので削除できます。

同時に、自動ページめくり機能も認識させる必要があります。

コード:

@config(age=10 * 24 * 60 * 60) 
    def board_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/t/"]').items(): 
            url = each.attr.href 
            if url.find('#reply')>0: 
                url = url[0:url.find('#')] 
            self.crawl(url, callback=self.detail_page, validate_cert=False) 
        for each in response.doc('a.page_normal').items(): 
            self.crawl(each.attr.href, callback=self.board_page, validate_cert=False) 
            #实现自动翻页功能

削除後のスクリーンショット:

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

自動ページめくりを実現した後のスクリーンショット:

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

此时我们已经可以匹配了所有的帖子的 url 了。

点击每个帖子后面的按钮就可以查看帖子具体详情了。

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

代码:

@config(priority=2) 
    def detail_page(self, response): 
        title = response.doc('h1').text() 
        content = response.doc('p.topic_content').html().replace('"', '\\"') 
        self.add_question(title, content)  #插入数据库 
        return { 
            "url": response.url, 
            "title": title, 
            "content": content, 
        }

插入数据库的话,需要我们在之前定义一个add_question函数。

#连接数据库 
def __init__(self): 
        self.db = MySQLdb.connect('localhost', 'root', 'root', 'wenda', charset='utf8') 
 
    def add_question(self, title, content): 
        try: 
            cursor = self.db.cursor() 
           sql = 'insert into question(title, content, user_id, created_date, comment_count)
            values ("%s","%s",%d, %s, 0)' % 
            (title, content, random.randint(1, 10) , 'now()');   
            #插入数据库的SQL语句 
            print sql 
            
            cursor.execute(sql) 
            print cursor.lastrowid 
            self.db.commit() 
        except Exception, e: 
            print e 
            self.db.rollback()

查看爬虫运行结果:

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

先debug下,再调成running。pyspider框架在windows下的bug

设置跑的速度,建议不要跑的太快,否则很容易被发现是爬虫的,人家就会把你的IP给封掉的

查看运行工作

查看爬取下来的内容

Python クローラーが V2EX Web サイトの投稿をクロールする練習をする

Python クローラーが V2EX Web サイトの投稿をクロールする練習をするPython クローラーが V2EX Web サイトの投稿をクロールする練習をする

然后再本地数据库GUI软件上查询下就可以看到数据已经保存到本地了。

自己需要用的话就可以导入出来了。

在开头我就告诉大家爬虫的代码了,如果详细的看看那个project,你就会找到我上传的爬取数据了。(仅供学习使用,切勿商用!)

当然你还会看到其他的爬虫代码的了,如果你觉得不错可以给个 Star,或者你也感兴趣的话,你可以fork我的项目,和我一起学习,这个项目长期更新下去。

最后:

代码:

# created by 10412 
# !/usr/bin/env python 
# -*- encoding: utf-8 -*- 
# Created on 2016-10-20 20:43:00 
# Project: V2EX 
 
from pyspider.libs.base_handler import * 
 
import re 
import random 
import MySQLdb 
 
class Handler(BaseHandler): 
    crawl_config = { 
    } 
 
    def __init__(self): 
        self.db = MySQLdb.connect('localhost', 'root', 'root', 'wenda', charset='utf8') 
 
    def add_question(self, title, content): 
        try: 
            cursor = self.db.cursor() 
          sql = 'insert into question(title, content, user_id, created_date, comment_count) 
         values ("%s","%s",%d, %s, 0)' % (title, content, random.randint(1, 10) , 'now()'); 
            print sql 
            cursor.execute(sql) 
            print cursor.lastrowid 
            self.db.commit() 
        except Exception, e: 
            print e 
            self.db.rollback() 
 
 
    @every(minutes=24 * 60) 
    def on_start(self): 
        self.crawl('https://www.v2ex.com/', callback=self.index_page, validate_cert=False) 
 
    @config(age=10 * 24 * 60 * 60) 
    def index_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/?tab="]').items(): 
            self.crawl(each.attr.href, callback=self.tab_page, validate_cert=False) 
 
 
    @config(age=10 * 24 * 60 * 60) 
    def tab_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/go/"]').items(): 
            self.crawl(each.attr.href, callback=self.board_page, validate_cert=False) 
 
 
    @config(age=10 * 24 * 60 * 60) 
    def board_page(self, response): 
        for each in response.doc('a[href^="https://www.v2ex.com/t/"]').items(): 
            url = each.attr.href 
            if url.find('#reply')>0: 
                url = url[0:url.find('#')] 
            self.crawl(url, callback=self.detail_page, validate_cert=False) 
        for each in response.doc('a.page_normal').items(): 
            self.crawl(each.attr.href, callback=self.board_page, validate_cert=False) 
 
 
    @config(priority=2) 
    def detail_page(self, response): 
        title = response.doc('h1').text() 
        content = response.doc('p.topic_content').html().replace('"', '\\"') 
        self.add_question(title, content)  #插入数据库 
        return { 
            "url": response.url, 
            "title": title, 
            "content": content, 
        }

以上就是Python爬虫实战之爬取 V2EX 网站帖子的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。