前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python网络爬虫(13)博客园用户信息爬取

python网络爬虫(13)博客园用户信息爬取

作者头像
嘘、小点声
发布2019-07-31 17:27:15
5610
发布2019-07-31 17:27:15
举报
文章被收录于专栏:嘘、小点声嘘、小点声

说明

这里只放代码,方案技术没有更变

代码说明

需要cookies绕过登录,使用selenium在Firefox下模拟。需要安装geck...?插件,另外,数据存储在sqlite,需要安装。

Spider.py

代码语言:javascript
复制
import HtmlDownloader
import HtmlParser
import DataOutput
import UrlManager
import re
from selenium import webdriver
class Spider(object):
    def __init__(self):
        self.downloader=HtmlDownloader.HtmlDownloader()
        self.parser=HtmlParser.HtmlParser()
        self.output=DataOutput.DataOutput()
        self.urlManager=UrlManager.UrlManager()
        self.driver=webdriver.Firefox()
     
    def crawl(self,root_url):
        content=self.downloader.download_root(root_url,self.driver)
        urls=self.parser.parser_url(content)
        self.urlManager.add_urls(urls)
        i=0
        while self.urlManager.new_urls_size()>0 and self.urlManager.old_urls_size()<2000:
            url=self.urlManager.get_new_url()
            i=i+1
            print(str(i)+':'+str(url))
            pattern=re.compile('/.*?/')
            user_name=re.findall(pattern,url)
            url='https://home.cnblogs.com'+user_name[1]
            
            content=self.downloader.download(self.driver,url)
            new_urls=self.parser.parser_url(content)
            self.urlManager.add_urls(new_urls)
            
            try:
                content=self.parser.parser_data(self.driver)
                self.output.store_data(content)
            except:
                i=i-1
                print('error url may not exits:'+self.driver.current_url)
        self.output.output_end()
        self.urlManager.save_status()
        #self.driver.close()
        print('ed')
if __name__=='__main__':
    spider=Spider()
    spider.crawl('https://www.cnblogs.com/')

UrlManager.py

代码语言:javascript
复制
import pickle
import hashlib
import re
class UrlManager():
    def __init__(self):
        self.old_urls=self.load_process('new_urls')
        self.new_urls=self.load_process('old_urls')
        
    def load_process(self,file_name):
        print('loading .')
        try:
            with open(file_name,'rb') as f:
                tmp=pickle.load(f)
                return tmp
        except:
            print('file may not exist.will create it')
        new_set=set()
        self.save_process(file_name,new_set)
        return new_set
    
    def save_process(self,file_name,data):
        with open(file_name,'wb') as f:
            pickle.dump(data,f)
    
    def save_status(self):
        self.save_process('new_urls',self.new_urls)
        self.save_process('old_urls',self.old_urls)
    
    def add_urls(self,urls):
        for url in urls:
            m=hashlib.md5()
            m.update(url.encode('utf8'))
            url_md5=m.hexdigest()[8:-8]
            if url not in self.new_urls and url_md5 not in self.old_urls:
                self.new_urls.add(url)
            
    def get_new_url(self):
        new_url=self.new_urls.pop()
        m=hashlib.md5()
        m.update(new_url.encode('utf8'))
        url_md5=m.hexdigest()[8:-8]
        self.old_urls.add(url_md5)
        return new_url
    
    def new_urls_size(self):
        return len(self.new_urls)
    
    def old_urls_size(self):
        return len(self.old_urls)

HtmlParser.py

代码语言:javascript
复制
import re
import json
class HtmlParser(object):
    def parser_url(self,content):
        pattern=re.compile(u'https://www.cnblogs.com/\w*/')
        all_urls=re.findall(pattern,content)
        all_urls=list(set(all_urls))
        return all_urls
    
    def parser_data(self,driver):
        dict={}
        user_id=driver.find_element_by_class_name('display_name').text
        all_message=driver.find_element_by_class_name('user_profile').text
        all_message=all_message.split('\n')
        all_message.insert(0,'用户ID:'+user_id+'\n')
        switch={'用户ID':'user_id',
                '姓名':'name',
                '性别':'sex',
                '出生日期':'birth_day',
                '家乡':'hometown',
                '现居住地':'live_place',
                '单位':'work_for',
                '工作状况':'job_status',
                '感兴趣的技术':'interest_technology',
                '最近目标':'recent_goal',
                '座右铭':'mark_words',
                '自我介绍':'introduce',
                '园龄':'blog_age',
                '博客':'blog_address',
                '婚姻':'marriage',
                '职位':'position',
                'QQ':'qq',
                'Email':'email'
            }
        key=''
        value=''
        for each in all_message:
            try:
                each=each.replace('\n','')
                key=switch[each.split(':')[0]]
                value=each.split(':')[1]
                dict[key]=value
            except:
                print('split error:'+each+'auto fixed..')
                value=value+each
                dict[key]=value
                print(dict)
        return dict

HtmlDownloader.py

代码语言:javascript
复制
import json
class HtmlDownloader(object):
    def download_root(self,url,driver):
        driver.get(url)
        with open('cookies.json', 'r', encoding='utf-8') as f:
            listCookies = json.loads(f.read())
        for cookie in listCookies:
            driver.add_cookie({
                'domain': cookie['domain'],  # 此处xxx.com前,需要带点
                'name': cookie['name'],
                'value': cookie['value']
            })
        driver.refresh()
        return driver.page_source
    
    def download(self,driver,url):
        driver.get(url)
        return driver.page_source

DataOutput.py

代码语言:javascript
复制
import sqlite3
class DataOutput(object):
    def __init__(self):
        self.cx=sqlite3.connect("cnblog.db")
        self.table_name='cnblog'
        self.create_table()
     
    def create_table(self):
        values='''
        id integer primary key autoincrement,
        user_id varchar(50) not null,
        name varchar(50),
        sex varchar(6),
        birth_day varchar(30),
        hometown varchar(50),
        live_place varchar(50),
        marriage varchar(20),
        position varchar(30),
        work_for varchar(50),
        job_status varchar(20),
        interest_technology varchar(200),
        recent_goal varchar(500),
        mark_words varchar(500),
        introduce varchar(500),
        blog_age varchar(30),
        blog_address varchar(100),
        qq varchar(15),
        email varchar(30)
        '''
        self.cx.execute('create table if not exists %s(%s)' %(self.table_name,values))
         
    def store_data(self,data):
        flag=0
        user_id=''
        for key,value in data.items():
            if flag==0:
                cmd="insert into %s (%s) values ('%s')" %(self.table_name,key,value)
                user_id=value
                flag=1
            else:
                cmd='update %s set %s="%s" where user_id="%s"' %(self.table_name,key,value,user_id)
            self.cx.execute(cmd)
        self.cx.commit()
         
    def output_end(self):
        self.cx.close()
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 说明
  • 代码说明
  • Spider.py
  • UrlManager.py
  • HtmlParser.py
  • HtmlDownloader.py
  • DataOutput.py
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档