這次的任務是爬取 中華講師網-中國最大講師平臺-找講師-培訓師-培訓講師首選網站 http://www.jiangshi.org/ 裏面的
紅色框框裏面的內容。
需要解決的問題第一是,有些電話和QQ只有登錄之後才能看到,因此需要模擬登錄之後的爬取。
感謝 Scrapy用Cookie實現模擬登錄 - 簡書 http://www.jianshu.com/p/887af1ab4200 提供的幫助。
讓我認識了 cookie,也想到之前從未考慮過的登錄網頁保存密碼,但好久不登網頁密碼失效的問題。
首先用 Chrome 來進入網站的登錄界面,F12 之後點擊 Network
下一步,登錄用戶之後(新用戶好像是要跳轉到完善用戶信息這頁面,但是爬蟲模擬的話,就直接進入主頁,暫時不用管完善資料這頁面,直接找下面的元素)
拿到這裏的 Cookie ,之後會用到的。這樣就可以模擬登錄用戶了,也不需要考慮驗證碼問題了,因爲 Cookie 就記錄一次的登錄信息:用戶名密碼和驗證碼。
之後就是對你所爬取的網站分析和解析爬取咯。結合我進去的坑,現在所想說的是:關鍵之處在於明白 scrapy 的 swiper 爬取到元素的屬性和 Request 的使用。
最經典的例子就是這個:當你明白如何獲取了一個方框裏面的 a 之後,我相信你已經在爬取元素方面沒有問題了。
hxs.select('//ul[@class="dscontainer list-teacher "]/li/div[@class="fl_l"]/a/@href').extract()
上面這個是無 <p> 的哦。歸根到底,就是結構必須一層一層的去分析。
最後,我此次爬取的網頁流程是:
登錄 -> 首頁 -> 講師(好多下一頁) -> 講師詳情
因此,程序中至少有 4 次跳轉,不要忘記講師還有好多下一頁。Request(url, 解析方向) 將會出現。
def parse1(self, response): hxs = HtmlXPathSelector(response) items = [] newurls = hxs.select('//ul[@class="dscontainer list-teacher "]/li/div[@class="fl_l"]/a/@href').extract() # 上面這個因爲不是 p 標籤裏面的,所以只有這一個 url ,所以說結構決定一切。 for i in range(0, 10): items.append(newurls[i]) for item in items: yield Request(item, callback=self.parse2) next_pages = hxs.select('//div[@class="page_box"]/a[@class="nextpage"]/@href') if next_pages: next_page = urlparse.urljoin(SITE_URL, next_pages[0].extract()) yield Request(next_page, callback=self.parse1)又是經典的例子, parse1 既要跳轉到 parse2 詳細資料的界面,又要跳轉到下一頁,也就是自己的界面
當你明白了以上要素之後,我相信你也能爬取到類似的網頁。
from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from scrapy.http import Request, FormRequest
from bestTeacher.items import BestteacherItem
from mongoengine import *
import urlparse
connect('teacher', host='192.168.52.128')
SITE_URL = "http://www.jiangshi.org/"
class InformationDoc(Document):
meta = {'collection': 'information'}
information = ListField()
contact = ListField()
money = ListField()
well = ListField()
class BestTeacher(BaseSpider):
name = "jiangshi"
allowed_domains = ["jiangshi.org"]
start_urls = [
"http://www.jiangshi.org/search"
]
def start_requests(self):
cookies = {
'js_clientid': 'a7bb2b6c-46d1-4efa-b3d6-26fe69c3ec04',
'ASP.NET_SessionId': 'xavy01gpqraxysbtno01dqmt',
'Hm_lvt_ff5146bd3e0db147ced120c6c2c9bcb2': '1492680652,1492757804',
'Hm_lpvt_ff5146bd3e0db147ced120c6c2c9bcb2': '1492760280',
'js.userName': '69D1F19715F81A6C023100340033003700310030003700000012AE393F72BAD2010012E21B7076BAD20100002F000000FCDA3EB0F53F024BD934284F731BC4E6A3974D9A'
}
return [FormRequest("http://www.jiangshi.org/account/login", cookies=cookies, callback=self.parse)]
def parse(self, response):
hxs = HtmlXPathSelector(response)
jiangshi = hxs.select('//div[@class="header-Box"]/div[@class="header"]/ul[@class="fl_l"]')
search = jiangshi.select('li/a/@href').extract()[1]
yield Request(search, callback=self.parse1)
def parse1(self, response):
hxs = HtmlXPathSelector(response)
items = []
newurls = hxs.select('//ul[@class="dscontainer list-teacher "]/li/div[@class="fl_l"]/a/@href').extract()
# 上面這個因爲不是 p 標籤裏面的,所以只有這一個 url ,所以說結構決定一切。
for i in range(0, 10):
items.append(newurls[i])
for item in items:
yield Request(item, callback=self.parse2)
next_pages = hxs.select('//div[@class="page_box"]/a[@class="nextpage"]/@href')
if next_pages:
next_page = urlparse.urljoin(SITE_URL, next_pages[0].extract())
yield Request(next_page, callback=self.parse1)
def parse2(self, response):
hxs = HtmlXPathSelector(response)
item = BestteacherItem()
# 這個是詳細資料的內容
contents = hxs.select('//div[@class="lecturer-ps"]/ul[@class="lecturer-ps2"]/li[@class="fl_l w600"]')
content = contents.select('p/text()').extract()
con = contents.select('p/span/text()').extract()
money = contents.select('p/b/text()').extract()
well = contents.select('p/a/text()').extract()
if len(content) == 15:
infor = InformationDoc(information=[content[0], content[1], content[2], content[14]], contact=con,
money=money, well=well)
infor.save()
elif len(content) == 14:
infor = InformationDoc(information=[content[0], content[1], content[2], content[13]], contact=con,
money=money, well=well)
infor.save()
elif len(content) == 13:
infor = InformationDoc(information=[content[0], content[1], content[2], content[12]], contact=con,
money=money, well=well)
infor.save()
elif len(content) == 12:
infor = InformationDoc(information=[content[0], content[1], content[2], content[11]], contact=con,
money=money, well=well)
infor.save()
item['information'] = content
item['contact'] = con
item['money'] = money
item['well'] = well
return item
PS: \r\n 可用 Python·字符串刪除或者替代就輕鬆解決