scrapy關於登錄和更多頁面的演示

這次的任務是爬取 中華講師網-中國最大講師平臺-找講師-培訓師-培訓講師首選網站  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·字符串刪除或者替代就輕鬆解決
發佈了235 篇原創文章 · 獲贊 27 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章