美文网首页
scrapy登录微博并爬取签约作者信息

scrapy登录微博并爬取签约作者信息

作者: 隐墨留白 | 来源:发表于2019-11-14 12:06 被阅读0次

    第一步,创建项目

    用scrapy命令创建一个weiboscrapy的项目,然后为了实现自动登录需要将settings.py中的COOKIES_ENABLED设置成True。

    第二步,模拟登录

    进行这一步的时候需要先了解微博的登录机制,然后才能实现scrapy的模拟登录。用start_requests()代替start_url。
    这里仅贴出一部分代码

    def start_requests(self):
        # 微博登录跳转url
        prelogin_url = 'https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.19)&_={}'.format(int(time.time() * 1000))  
        yield scrapy.Request(url=prelogin_url,callback=self.get_formdata,headers=self.headers)
    
    第三步,获取数据

    在获取数据之前,需要先把items.py文件补充完整。

    class WeiboscrapyItem(scrapy.Item):
        user_homepage_url = scrapy.Field()
        user_name = scrapy.Field()
        user_image_url = scrapy.Field()
        user_verify = scrapy.Field()
        user_address = scrapy.Field()
        user_job = scrapy.Field()
        user_follow_num = scrapy.Field()
        user_fans_num = scrapy.Field()
        user_profile_num = scrapy.Field()
        user_detail = scrapy.Field()
        user_tags = scrapy.Field()
        user_school = scrapy.Field()
        user_work = scrapy.Field()
    

    获取数据

    def parse(self, response):
        users_cards = response.xpath('//div[@id="pl_user_feedList"]/div[@class="card card-user-b s-pg16 s-brt1"]')
        for user_card in users_cards:
            item = WeiboscrapyItem()
            # 作家主页
            item['user_homepage_url'] = user_card.xpath('./div[@class="avator"]/a/@href').extract()[0]
            # 作者头像
            item['user_image_url'] = user_card.xpath('./div[@class="avator"]/a/img/@src').extract()[0]
            # 作者名
            item['user_name'] = user_card.xpath('./div[@class="info"]/div/a[1]/text()').extract()[0]
            # 微博个人认证 类型
            item['user_verify'] = user_card.xpath('./div[@class="info"]/div/a[2]/i/@class').extract()[0]
            # 作者工作地址
            item['user_address'] = ''.join(''.join(user_card.xpath('./div[@class="info"]/p[1]/text()').extract()).split())
            # 作者工作
            item['user_job'] = ' '.join(user_card.xpath('./div[@class="info"]/p[2]/text()').extract()[0].split())
            # 关注数
            item['user_follow_num'] = user_card.xpath('./div[@class="info"]/p[3]/span[1]/a/text()').extract()[0]
            # 粉丝数
            item['user_fans_num'] = user_card.xpath('./div[@class="info"]/p[3]/span[2]/a/text()').extract()[0]
            # 微博数
            item['user_profile_num'] = user_card.xpath('./div[@class="info"]/p[3]/span[3]/a/text()').extract()[0]
            
            item['user_detail'] = '',
            item['user_tags'] = '',
            item['user_school'] = '',
            item['user_work'] = ''
            
            # 除了上面的3个标签,还有几个p标签
            number = len(user_card.xpath('./div[@class="info"]/p')) - 3
            #  有4个p标签
            if number == 4:
                # 作者简介
                item['user_detail'] = user_card.xpath('./div[@class="info"]/p[4]/text()').extract()[0]
                # 作者标签
                item['user_tags'] = ''.join(user_card.xpath('./div[@class="info"]/p[5]/a/text()').extract())
                # 作者教育信息
                item['user_school'] = ' '.join(user_card.xpath('./div[@class="info"]/p[6]/a/text()').extract())
                # 作者职业信息
                item['user_work'] = ' '.join(user_card.xpath('./div[@class="info"]/p[7]/a/text()').extract())
            #  有3个p标签
            elif number == 3:
                # 作者简介
                item['user_detail'] = user_card.xpath('./div[@class="info"]/p[4]/text()').extract()[0]
                # 作者标签
                item['user_tags'] = ' '.join(user_card.xpath('./div[@class="info"]/p[5]/a/text()').extract())
                
                html_content = user_card.xpath('./div[@class="info"]/p[last()]/text()').extract()[0]
                xinxi = html_content.split(':')[0]
                if xinxi == '教育信息':
                    item['user_school'] = ' '.join(user_card.xpath('./div[@class="info"]/p[last()]/a/text()').extract())
                # xinxi == '职业信息'
                else:
                    item['user_work'] = ' '.join(user_card.xpath('./div[@class="info"]/p[last()]/a/text()').extract())
            #  有2个p标签
            elif number == 2:
                html_content = user_card.xpath('./div[@class="info"]/p[last()]/text()').extract()[0]
                xinxi = html_content.split(':')[0]
                if xinxi == '标签':
                    # 作者简介
                    item['user_detail'] = user_card.xpath('./div[@class="info"]/p[last()-1]/text()').extract()[0]
                    # 作者标签
                    item['user_tags'] = ' '.join(user_card.xpath('./div[@class="info"]/p[last()]/a/text()').extract())
                # len(xinxi) == 4
                else:
                    if xinxi == '教育信息':
                        item['user_school'] = ' '.join(user_card.xpath('./div[@class="info"]/p[last()]/a/text()').extract())
                    # xinxi == '职业信息'
                    else :
                        item['user_work'] = ' '.join(user_card.xpath('./div[@class="info"]/p[last()]/a/text()').extract())
                    html_data = user_card.xpath('./div[@class="info"]/p[last()-1]/text()').extract()[0]
                    if html_data[:2] == '简介':
                        # 作者简介
                        item['user_detail'] = user_card.xpath('./div[@class="info"]/p[last()-1]/text()').extract()[0]
                    # html_data[:2] == '标签'
                    else :
                        # 作者标签
                        item['user_tags'] = ' '.join(user_card.xpath('./div[@class="info"]/p[last()-1]/a/text()').extract())
            # number == 1  只有一个p标签
            else:
                html_data = user_card.xpath('./div[@class="info"]/p[last()]/text()').extract()[0]
                if html_data[:2] == '简介':
                    # 作者简介
                    item['user_detail'] = user_card.xpath('./div[@class="info"]/p[last()]/text()').extract()[0]
                else:
                    # 作者标签
                    item['user_tags'] = ' '.join(user_card.xpath('./div[@class="info"]/p[last()]/a/text()').extract())
            yield item
    

    看到这些代码你是不是想说为什么会这么多?,因为最后四条数据不一定存在,而且在HTML中这些数据都属于p标签的内容且p标签没有任何属性,这就要求你要根据内容来判断这个数据该存放到哪个item字段中。

    第四步 数据存储

    存储数据一般在pipelines.py文件中,别忘了在settings.py文件中将管道文件开启哦。

    class WeiboscrapyPipeline(object):
        def open_spider(self,spider):
           # self.data_csv = pd.DataFrame(columns=('主页链接','头像','昵称','微博认证','地址','工作','关注','粉丝','微博','简介','标签','教育信息','职业信息'))
            self.data_csv = pd.DataFrame(columns=('user_homepage_url','user_name','user_image_url','user_verify','user_address','user_job',
                     'user_fans_num','user_follow_num','user_profile_num','user_detail','user_school','user_tags','user_work'))
            self.index = 0
        def process_item(self, item, spider):
            new_h = [item['user_homepage_url'],
                item['user_image_url'],
                item['user_name'],
                item['user_verify'],
                item['user_address'],
                item['user_job'],
                item['user_follow_num'],
                item['user_fans_num'],
                item['user_profile_num'],
                item['user_detail'],
                item['user_tags'],
                item['user_school'],
                item['user_work']]
        
            self.data_csv.loc[self.index] = new_h
            self.index += 1
       
            return item
    
        def close_spider(self,spider):
            print('*'*10)
            self.data_csv.to_csv('user_data.csv',index=True)
    

    结果展示:

    一共爬取了50页的信息(最多显示50页):


    data.png

    一共988条数据,为什么不是整数呢?因为有的页面的数据是不足20条的,有17/19条的页面。

    相关文章

      网友评论

          本文标题:scrapy登录微博并爬取签约作者信息

          本文链接:https://www.haomeiwen.com/subject/ydtrictx.html