首頁 > 後端開發 > Python教學 > Python爬蟲實戰之爬取 V2EX 網站帖子

Python爬蟲實戰之爬取 V2EX 網站帖子

高洛峰
發布: 2016-11-07 16:43:35
原創
1943 人瀏覽過

背景:

PySpider:一個國人編寫的強大的網路爬蟲系統並帶有強大的WebUI。採用Python語言編寫,分散式架構,支援多種資料庫後端,強大的WebUI支援腳本編輯器,任務監視器,專案管理器以及結果檢視器。線上範例: http://demo.pyspider.org/

官方文件: http://docs.pyspider.org/en/l...

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

本文爬蟲代碼Github 網址:https://github.com/zhisheng17...

更多精彩文章可以在微信公眾號:猿blog 閱讀到,歡迎關注。

說了這麼多,我們還是來看正文吧!

前提:

你已經安裝好了Pyspider 和MySQL-python(保存資料)

如果你還沒安裝的話,請看看我的前一篇文章,防止你也走彎路。

Pyspider 框架學習時走過的一些坑

HTTP 599: SSL certificate problem: unable to get local issuer certificate錯誤

我所遇到的一些錯誤:

框架爬取V2EX 網站的貼文中的問題和內容,然後將爬取的資料保存在本地。

Python爬蟲實戰之爬取 V2EX 網站帖子V2EX 中大部分的帖子查看是不需要登入的,當然也有些帖子是需要登陸後才能夠查看的。 (因為後來爬取的時候發現一直error ,查看具體原因後才知道是需要登錄的才可以查看那些帖子的)所以我覺得沒必要用到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 的dashboard 的右下角,點選「Create」按鈕

的替換
@every(minutes=24 * 60) 
    def on_start(self): 
        self.crawl('https://www.v2ex.com/', callback=self.index_page, validate_cert=False)
登入後複製

self.crawl 告訴pyspider 抓取指定頁面,然後使用callback 函數對結果進行解析。 Python爬蟲實戰之爬取 V2EX 網站帖子

@every) 修飾器,表示 on_start 每天會執行一次,這樣就能抓到最新的貼文了。

validate_cert=False 一定要這樣,否則會報HTTP 599: SSL certificate problem: unable to get local issuer certificate錯誤

首頁:

點擊綠色的run 執行,你會看到上面的首頁:

點擊綠色的run 執行,你會看到上面的1切換到follows 面板,點選綠色的播放鈕:

Python爬蟲實戰之爬取 V2EX 網站帖子

第二張截圖一開始是出現這個問題了,解決辦法看前面寫的文章,後來問題就不再會出現了。 Python爬蟲實戰之爬取 V2EX 網站帖子

Tab 清單頁 :

在 tab 清單頁 中,我們需要提取所有的主題清單頁 的 URL。你可能已經發現了,sample handler 已經提取了非常多大的URLPython爬蟲實戰之爬取 V2EX 網站帖子

代碼:

@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)
登入後複製

由於帖子列表頁和tab列表頁長的並不一樣,在這裡新建了一個callback 為self.tab_page

@config (age=10 24 60 * 60) 在這表示我們認為10 天內頁面有效,不會再進行更新抓取

Go列表頁:

代碼:Python爬蟲實戰之爬取 V2EX 網站帖子

@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):詳情頁(T)

你可以看到結果裡面出現了一些reply的東西,對於這些我們是可以不需要的,我們可以去掉。

Python爬蟲實戰之爬取 V2EX 網站帖子同時我們還需要讓他自己實現自動翻頁功能。

程式碼:

@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 網站帖子

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

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

Python爬蟲實戰之爬取 V2EX 網站帖子

代码:

@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 網站帖子

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

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

查看运行工作

查看爬取下来的内容

Python爬蟲實戰之爬取 V2EX 網站帖子

Python爬蟲實戰之爬取 V2EX 網站帖子Python爬蟲實戰之爬取 V2EX 網站帖子

然后再本地数据库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中文网(m.sbmmt.com)!


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板