scrapy关于登录和更多页面的演示

来源:互联网 发布:王家卫表白方式 知乎 编辑:程序博客网 时间:2024/06/06 15:53

这次的任务是爬取 中华讲师网-中国最大讲师平台-找讲师-培训师-培训讲师首选网站  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 BaseSpiderfrom scrapy.selector import HtmlXPathSelectorfrom scrapy.http import Request, FormRequestfrom bestTeacher.items import BestteacherItemfrom mongoengine import *import urlparseconnect('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·字符串删除或者替代就轻松解决

0 0