本節內容
在某些時候,網站的某些內容的訪問不僅僅需要用戶登錄,而且需要回復才能看到全部內容,如下圖。所以我們需要通過模擬表單提交實現用爬蟲回帖,進而獲取到隱藏內容。本節就來介紹模擬表單提交的方法,github地址:https://github.com/kongtianyi/heartsong/tree/reply
前提
你已經瞭解了HTML表單的相關知識(這個很好找)和scrapy的簡單功能以及配置Cookie,如果還不會,請戳Scrapy定向爬蟲教程(五)——保持登陸狀態。
分析表單
在帖子頁面的底部找到表單,右鍵檢查,查看這一部分的源代碼
我們知道,表單提交的數據都在<form>
標籤裏,明顯這裏也沒有多選框之類的東西,我們只需要把有name屬性的元素如<input>
和<textarea>
都找出來就好了
圖中提到這時的提交地址並不全,咋辦呢,我們就先手動回覆一下,看看都發生了什麼
轉碼的話,網上有許多現成的工具,也可以自己寫個小腳本。
代碼
把上面的四張圖看完並且實踐之後局勢就很清晰了,剩下的就是輕輕鬆鬆寫代碼了。ok,上代碼,思路就是先訪問一個頁面,查找這個頁面是否需要回復可見,如果需要,則回覆之。這裏我把判斷是否需要回復註釋掉了,隨便一個帖子id直接運行就會回覆。推薦移步去github上把代碼下載到本地來看,重要部分的我都寫了註釋。
因爲本節只介紹回覆,所以只要網頁上出現了我們用爬蟲回覆出來的內容就算成功了,就不跟下載分析什麼的整合到一起了。
heartsong_spider.py
# -*- coding: utf-8 -*-
# import scrapy # 可以用這句代替下面三句,但不推薦
from scrapy.spiders import Spider
from scrapy.selector import Selector
from scrapy import Request
from scrapy import FormRequest # 帶表單的請求
import random
class HeartsongSpider(Spider):
name = "heartsong"
allowed_domains = ["heartsong.top"] # 允許爬取的域名,非此域名的網頁不會爬取
start_urls = [
# 起始url,這裏只回復這一個頁面,多個頁面連續爬取請看mast分支
"http://www.heartsong.top/forum.php?mod=viewthread&tid=136"
]
# 用來保持登錄狀態,可把chrome上拷貝下來的字符串形式cookie轉化成字典形式,粘貼到此處
cookies = {'QGfS_2132_lastvisit': '1478302547', 'QGfS_2132_seccode': '1.fa43f9a3cb6efdd635', 'QGfS_2132_smile': '1D1', 'QGfS_2132_lip': '202.102.144.8%2C1478307120', 'QGfS_2132_ulastactivity': '29d9HUFm42onqH11DCnfZh8MN%2FFmPt0TEe15bNf2oeHflNI%2BJiwJ', 'QGfS_2132_auth': 'd713PkyUoDmnvp%2BestZH5F4lo%2BK0ewxTT1A02ulX%2FbRufbG%2B6T%2FIATHA5uYS9yoQzeNH3qz%2BupceANNs4IWF9w', 'QGfS_2132_nofavfid': '1', 'QGfS_2132_lastact': '1478308730%09misc.php%09patch', 'QGfS_2132_viewid': 'tid_196', 'QGfS_2132_sid': 'wbBi5Q', 'pgv_info': 'ssi', 'QGfS_2132_st_p': '14%7C1478308725%7Cacf78675ed42e1121abb06c3d6b494cb', 'QGfS_2132_visitedfid': '36D48', 'QGfS_2132_saltkey': 'GN4BcGg4', 'QGfS_2132_lastcheckfeed': '14%7C1478307120', 'QGfS_2132_forum_lastvisit': 'D_48_1478306883D_36_1478306901', 'QGfS_2132_st_t': '0%7C1478306901%7C6c837d3b8b5892fd86ea3bb15bf4426e', 'pgv_pvi': '8246475216', 'QGfS_2132_security_cookiereport': '12adOGUyzEnhcSY%2FZb5MgT52%2BxCPi3KZn%2Fh7pNHlxvWLnqDlLbAd'}
# 發送給服務器的http頭信息,有的網站需要僞裝出瀏覽器頭進行爬取,有的則不需要
headers = {
'Connection': 'keep - alive',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36'
}
# 對請求的返回進行處理的配置
meta = {
'dont_redirect': True, # 禁止網頁重定向
'handle_httpstatus_list': [301, 302] # 對哪些異常返回進行處理
}
def start_requests(self):
"""
這是一個重載函數,它的作用是發出第一個Request請求
:return:
"""
# 帶着headers、cookies去請求self.start_urls[0],返回的response會被送到
# 回調函數parse中
yield Request(self.start_urls[0],
callback=self.parse, headers=self.headers,
cookies=self.cookies, meta=self.meta)
def parse(self, response):
"""
用以處理主題貼的首頁
:param response:
:return:
"""
selector = Selector(response) # 創建選擇器
table = selector.xpath('//*[starts-with(@id, "pid")]') # 取出所有的樓層
if not table:
# 這個鏈接內沒有一個樓層,說明此主題貼可能被刪了,
# 把這類url保存到一個文件裏,以便審查原因
print "bad url!"
f = open('badurl.txt', 'a')
f.write(response.url)
f.write('\n')
f.close()
return
# 如有回覆可見的隱藏區域,進行回覆
# locked = selector.xpath('//*[@class="locked"]')
# if locked:
# re_a = locked.xpath('a/text()')
# if re_a and re_a.extract()[0] == u'回覆':
# 找到表單要提交到的地址
form_action = selector.xpath('//*[@id="fastpostform"]/@action').extract()[0]
action = "http://www." + self.allowed_domains[0] + "/" + form_action + "&inajax=1"
replys = [
'回复看看 有用不',
'厉害厉害,谢谢分享!'
] # utf-8編碼的一些回覆,具體使用什麼編碼要看具體的網站的編碼
reply = replys[random.randint(0, 1)] #防止被管理員識別是機器回覆,要隨機一下
formdata = {
'formhash': selector.xpath('//*[@id="fastpostform"]/table/tr/td[2]/input[2]/@value').extract()[0],
'usesig': selector.xpath('//*[@id="fastpostform"]/table/tr/td[2]/input[3]/@value').extract()[0],
'subject': selector.xpath('//*[@id="fastpostform"]/table/tr/td[2]/input[4]/@value').extract()[0],
'posttime': selector.xpath('//*[@id="posttime"]/@value').extract()[0],
'message': reply
} # 表單數據,是從網頁表單代碼裏分析出來的
# 發出帶表單的請求,當然,要有cookie
yield FormRequest(action, callback=self.finish,
headers=self.headers,
cookies=self.cookies,
meta=self.meta,
formdata=formdata)
return
def finish(self, response):
print "reply seccess!"
效果
與正常手動回覆無異。
小結
本節介紹瞭如何分析表單並回帖,希望對你有所幫助!剩下的部分還有配置代理和發送郵件,如果需要,請通知我更新,哈,懶癌需要驅動。