背景:
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 網站的貼文中的問題和內容,然後將爬取的資料保存在本地。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 函數對結果進行解析。
@every) 修飾器,表示 on_start 每天會執行一次,這樣就能抓到最新的貼文了。 validate_cert=False 一定要這樣,否則會報HTTP 599: SSL certificate problem: unable to get local issuer certificate錯誤首頁:點擊綠色的run 執行,你會看到上面的首頁:點擊綠色的run 執行,你會看到上面的1切換到follows 面板,點選綠色的播放鈕:第二張截圖一開始是出現這個問題了,解決辦法看前面寫的文章,後來問題就不再會出現了。
Tab 清單頁 :在 tab 清單頁 中,我們需要提取所有的主題清單頁 的 URL。你可能已經發現了,sample handler 已經提取了非常多大的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)
代碼:
@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) #实现自动翻页功能
去掉後的運行截圖:
實現自動翻頁後的截圖:此时我们已经可以匹配了所有的帖子的 url 了。
点击每个帖子后面的按钮就可以查看帖子具体详情了。
代码:
@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()
查看爬虫运行结果:
先debug下,再调成running。pyspider框架在windows下的bug
设置跑的速度,建议不要跑的太快,否则很容易被发现是爬虫的,人家就会把你的IP给封掉的
查看运行工作
查看爬取下来的内容
然后再本地数据库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)!