Sina微博爬取@pyspider
這是一篇不應該寫的文章,都寫了,針對特定“方式”的爬蟲也就沒法爬了。
1、模擬登入的一些文章:
解析新浪微博的登入過程(2013-12-23): http://www.cnblogs.com/houkai/p/3487816.html
Python模擬登陸新浪微博(2013-12-24): http://www.cnblogs.com/houkai/p/3488468.html
2014_新浪微博模擬登陸_python(2014-08-08): http://blog.csdn.net/springzfx/article/details/38435069
Wap的weibo.cn模擬登入@2012年11月8日: http://qinxuye.me/article/simulate-weibo-login-in-python/
wap端模擬登陸
2、Chrome下登入請求的所有資訊,其中像random欄位必須通過先get一次登入頁來得到,通過分析chrome開發工具下的這些資訊基本就Ok,再就是可以複製curl指令看看也很方便:
--------------- General Info: Remote Address:180.149.153.4:80 Request URL:http://login.weibo.cn/login/?rand=1623920428&backURL=http%3A%2F%2Fweibo.cn&backTitle=%E6%89%8B%E6%9C%BA%E6%96%B0%E6%B5%AA%E7%BD%91&vt=4 Request Method:POST Status Code:302 Found
---------------------- Response Headers view source Connection:close Content-Encoding:gzip Content-Length:20 Content-Type:text/html Date:Thu, 05 Nov 2015 08:11:34 GMT Location:http://newlogin.sina.cn/crossDomain/?g=4ugB9b801ltp<span style="font-family: Arial, Helvetica, sans-serif;">*************</span>Q&t=1446711094&m=05b4&r=&u=http%3A%2F%2Fweibo.cn%3Fgsid%3D4ugB9b801ltp<span style="font-family: Arial, Helvetica, sans-serif;">*************</span>Q%26PHPSESSID%3D%****%3D4&cross=1&st=ST-NTc0MDUwMTQ4Ng==-1446711094-tc-F903CC8EC38C7F499D7D227DA862A39E,ST-NTc0MDUwMTQ4Ng==-1446711094-tc-F4B911C868B51E768875EB15BBAE6E83&vt=4 Server:Apache Set-Cookie:SUB=_2A257P39mDeTxGeNJ71IU8C_IwzqIHXVYwAEurDV6PUJbrdAKLVjSkW03kbkKkoC7qLmx-EiB5I-Diw91GQ..; expires=Sat, 05-Dec-2015 08:11:34 GMT; path=/; domain=.weibo.cn; httponly Set-Cookie:gsid_CTandWM=4ugB9b801ltp*************Q; expires=Sat, 05-Dec-2015 08:11:34 GMT; path=/; domain=.weibo.cn; httponly SINA-LB:aGEuMTY1LmcxLnlmLmxiLnNpbmFub2RlLmNvbQ== SINA-TS:MzU2ZWMzNjggMCAwIDAgNSA5Mwo= Vary:Accept-Encoding x-debug:172.16.140.196 X-Log-Uid:5740501486
------------------
Request Headers view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:208
Cookie:_T_WM=086561716ab68ff3c6e589cc5152ed66
DNT:1
Host:login.weibo.cn
Origin:http://login.weibo.cn
Referer:http://login.weibo.cn/login/
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
-------------------
Query String Parameters
view source
view URL encoded
rand:1623920428
backURL:http://weibo.cn
backTitle:手機新浪網
vt:4
-------------------
Form Data
view source
view URL encoded
mobile:[email protected]
password_4509:user_password
remember:on
backURL:http%3A%2F%2Fweibo.cn
backTitle:手機新浪網
tryCount:
vk:4509_290b_1897615582
submit:登入
3、上一個在pyspider上能走通weibo.cn爬取示例程式碼,這個程式碼的缺憾就是如果頻繁登陸可能會出驗證碼,目前還沒加驗證碼識別特性。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2015-11-05 11:41:06
# Project: sinaweibo
# SinaUser:[email protected]
from pyspider.libs.base_handler import *
class Handler(BaseHandler):
crawl_config = {
'headers': {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko)',
}
}
@every(minutes=24 * 60)
def on_start(self):
self.crawl('http://login.weibo.cn/login/', callback=self.login)
@config(age=1 * 24 * 60 * 60)
def login(self, response):
cookies = response.cookies
base_url = 'http://login.weibo.cn/login/'
url = base_url + response.doc("form").attr("action")
data = {}
for each in response.doc("form input"):
data[each.name]=each.value
if each.name == "mobile":
data["mobile"] = "[email protected]"
if each.type == "password":
data[each.name] = "password"
headers = {}
headers["Content-Type"]="application/x-www-form-urlencoded"
headers["Referer"]="http://login.weibo.cn/login/"
headers["Origin"]="http://login.weibo.cn"
headers["Referer"]="http://login.weibo.cn/login/"
self.crawl(url, callback=self.login_ok,data=data,cookies=cookies,headers=headers,method="POST")
@config(priority=2)
def login_ok(self, response):
'''
return {
"url": response.url,
"headers": response.headers,
"cookies": response.cookies,
"status":response.status_code,
"text":response.text,
}
'''
self.crawl("http://weibo.cn/yumayin",
cookies=response.cookies,callback=self.index_page)
def index_page(self, response):
weibos = []
for each in response.doc("div.c").items():
#each.find("span.kt"):
if each.find("span.kt").html()!= None:
continue
#if each.find("span.ctt")!= None:
if each.find("span.ctt").html()!= None:
weibos.append(each.find("span.ctt").html())
return weibos
4、phantomjs啟動的一個問題,官方的文件好像有點問題,真正的啟動命令是啟動phantomjs proxy選項:
pyspider --phantomjs-proxy="localhost:25555" -c config.json
這個解決方法是參考:http://blog.csdn.net/jxnu_xiaobing/article/details/44983757
還有可以把執行元件改成all,也可以全部啟動:
pyspider -c config.json all
5、啟用phantomjs以後,JS抓取返回HTML是亂碼的問題,官方給出的回答:Phantomjs doesn't support gzip, don't set Accept-Encoding header with gzip.
6、重複任務的判定問題,get某登入地址,然後post該登入地址登入,第二步操作可能失敗,pyspider判定重複任務完全看URL地址,部署以後,第二個請求會因為age設定問題,直接被拒。
7、DB資料庫選擇的問題,談這個問題,首先說說儲存方式,projectdb和taskdb,一般我們使用者不用訪問,就不用說了,resultdb裡面,除了我們解析返回的result資料,同時儲存的還有id、updatetime、url,而我們返回的result資料會被json序列化為二進位制字串,這種字串只包含字母之類鍵盤有的字串,所以你不論用mongodb還是RDB,儲存其實都是一層資料,不過在resultdb裡面,如果我們做掛鉤儲存的話,Mongodb會方便一點,起碼不用改資料定義模式。做這類對pyspider的hacking開發,可以到pyspider的目錄裡面直接修改程式碼。
8、官網docs上沒有redis帶密碼連線字串,先後在github issues和django-redis文件上找到這個設定格式,後者的更全面一點:
redis://[:password]@localhost:6379/0
rediss://[:password]@localhost:6379/0
unix://[:password]@/path/to/socket.sock?db=0
不過要使用這個帶password的連線字串,pyspider版本得升級到最新版本。
9、每個爬蟲的入口函式一定要用@every來裝飾,千萬不要寫成別的週期控制裝飾器,否則你的這個爬蟲專案永遠不會被排程器啟動。