Python爬虫: 《经济研究》研究热点和主题分析

发布时间:2020-03-07 阅读 756

Stata 连享会   主页 || 视频 || 推文

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

课程详情 https://gitee.com/arlionn/Course   |   lianxh.cn

课程主页 https://gitee.com/arlionn/Course

作者:王文韬 (山东大学)
邮箱:190138445@qq.com

Python爬虫: 《经济研究》研究热点和主题分析


目录


0. 背景

使用 Python 爬虫的好处

爬虫,顾名思义,指我们沿着网络抓取自己的猎物(数据)。使用这种方法,我们可以向网站发起请求,获取资源后分析并提取有用数据。 相比与其他静态编程语言,如 java,c#,C++,python 抓取网页文档的接口更简洁;相比其他动态脚本语言,如 perl,shell,python 的 urllib2 包提供了较为完整的访问网页文档的 API。

此外, 抓取网页有时候需要模拟浏览器的行为,譬如模拟用户登陆、模拟 session/cookie 的存储和设置。在 python 里有非常优秀的第三方包帮你搞定 ,如requests

抓取的网页通常需要处理,比如过滤 html 标签,提取文本等。python 的 beautifulsoap提供了简洁的文档处理功能 ,能用极短的代码完成大部分文档的处理。

本文使用工具

1)本文分析网页时使用 fildder 进行抓包,配合谷歌浏览器 F12 检查。使用文本 IDE、vscode 编写爬虫代码,requests 库获取网页信息,beautifulsoup 库和正则表达式 re 解析网页,xlwt 写入为 xls 格式。

2)数据分析与可视化工具为 Jupyter Notebook,用 Pandas 库进行数据处理,matplotlib 画图等。

本文目标

本文目标为模拟知网的高级搜索,获取特定学术期刊的历史论文信息。 以国内经济学顶刊《经济研究》为例,获取其 2000-2018 年的全部文章数据。具体包括摘要页的题名、作者、来源、发表时间、数据库、被引、下载,以及详细页面的单位、关键字、摘要等信息,以探究近二十年来国内核心期刊发文概况及研究热点的变动趋势。

本文主要由几下三部分构成:

  1. 对爬取网页进行分析;
  2. 爬虫构建;
  3. 对爬取数据进行处理和简析。

1. 网页分析

本文需要的高级检索页面如下:

高级检索页面
高级检索页面

爬虫实现上来看,需要在维持 session 的情况下,多次向服务器发送信息,来获得目标页面。主要有三个要实现的动作: 网页(知网)高级检索、打开详细界面与翻页。

上述三个动作的实现,关键在于信息的有效提交和获取。此处有两大难点(这是 Python 爬虫的基本功,可参考北理工嵩天老师MOOC课程学习巩固):

(1) 抓包后,哪些是需要关注的请求? 答: 本文将主要请求提取出来,知网中的每一个请求都是按照请求方法的作用进行命名,这在很大程度上能够帮助我们快速定位到我们需要的请求。 多次尝试后,我们大致定位出每个请求的信息,详情见下页图。

(2) 找到需要关注的请求后,如何构建请求? 答: 具体来说,每次 get 请求中,我们上传的参数如何设置。根据 fildder 我们可以获取需要上传的参数。这些参数中有很多都是固定的,也有一部分是动态的。动态的一般就是检索条件需要的,需要注意是如果没有规定某个条件,那这个参数是不传递的。下面列出了一部分常用的传递参数,更多参数大家自己通过这个方法查看。至此我们了解的如何获取页面请求以及如何设置搜索参数,下面我们可以开始进行爬虫代码编写。

浏览器正常浏览下,三个动作的抓包如下所示:

浏览器正常浏览下,三个动作的抓包
浏览器正常浏览下,三个动作的抓包

爬虫 requests 模拟下,三个动作的抓包:

爬虫 requests 模拟下,三个动作的抓包
爬虫 requests 模拟下,三个动作的抓包

爬取网页数据需要设置的参数:

需要设置的参数
需要设置的参数

上图红框中参数信息详情:

参数信息
参数信息

2. 爬虫构建

第一,需要设置我们的报文信息,模拟真人访问,用于回避网站的审查

 def crawl_headers(self):
        headers = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36',
            'Host':
            'kns.cnki.net',
            'Connection':
            'keep-alive',
            'Cache-Control':
            'max-age=0',
        }
        return headers

第二,发送请求,并捕捉到我们所需的内容(核心关键步骤)

    def search_reference(self, ueser_input):
        '''
        第一次发送post请求
        再一次发送get请求,这次请求没有写文献等东西
        两次请求来获得文献列表
        '''
        #删除了些参数,并改变action赋值,便可完成时间区间的限定
        static_post_data = {
            'action': '44',
            'NaviCode': '*',
            'ua': '1.21',
            'isinEn': '1',
            'PageName': 'ASP.brief_result_aspx',
            'DbPrefix': 'SCDB',
            'DbCatalog': '中国学术文献网络出版总库',
            'ConfigFile': 'SCDB.xml',
            'db_opt': 'CJFQ,CDFD,CMFD,CPFD,IPFD,CCND,CCJD',  # 搜索类别(CNKI右侧的)
            'his': '0',
            '__': time.asctime(time.localtime()) + ' GMT+0800 (中国标准时间)'
        }
        # 将固定字段与自定义字段组合
        post_data = {**static_post_data, **ueser_input}
        #print(post_data)
        # 必须有第一次请求,否则会提示服务器没有用户
        first_post_res = self.session.post(
            SEARCH_HANDLE_URL, data=post_data, headers=HEADER)
        # get请求中需要传入第一个检索条件的值
        #key_value = quote(ueser_input.get('magazine_value1'))
        #self.get_result_url = GET_PAGE_URL + first_post_res.text + '&t=1544249384932&keyValue=' + key_value + '&S=1&sorttype='
        self.get_result_url = GET_PAGE_URL + first_post_res.text + '&t=1562315821144&keyValue=&S=1&sorttype='
        #print(self.get_result_url)
        # 检索结果的第一个页面
        second_get_res = self.session.get(self.get_result_url, headers=HEADER)
        change_page_pattern_compile = re.compile(
            r'.*?pagerTitleCell.*?<a href="(.*?)".*')
        self.change_page_url = re.search(change_page_pattern_compile,
                                         second_get_res.text).group(1)
        self.parse_page(
            self.pre_parse_page(second_get_res.text), second_get_res.text)

其中,要注意对函数 parse_pageget_detail_page 的构建:

1)parse_page方法用来捕捉每一页我们要捕捉的内容,我们根据 class 和 name 对页面中每个 table 的内容进行捕捉,同时在这里使用beautifulsoap方法对捕捉网页内容进行文本处理。

parse_page 方法代码如下:

       def parse_page(self, download_page_left, page_source):
        '''
        保存页面信息
        解析每一页的下载地址
        '''
        soup = BeautifulSoup(page_source, 'lxml')
        # 定位到内容表区域
        tr_table = soup.find(name='table', attrs={'class': 'GridTableContent'})
        # 处理验证码
        try:
            # 去除第一个tr标签(表头)
            tr_table.tr.extract()
        except Exception as e:
            logging.error('出现验证码')
            return self.parse_page(
                download_page_left,
                crack.get_image(self.get_result_url, self.session,
                                page_source))
        # 遍历每一行
        for index, tr_info in enumerate(tr_table.find_all(name='tr')):
            tr_text = ''
            download_url = ''
            detail_url = ''
            # 遍历每一列

            for index, td_info in enumerate(tr_info.find_all(name='td')):
                # 因为一列中的信息非常杂乱,此处进行二次拼接
                td_text = ''
                for string in td_info.stripped_strings:
                    td_text += string
                tr_text += td_text + '@'
                #with open(
                #        'data/ReferenceList.txt', 'a',
                #        encoding='utf-8') as file:
                #    file.write(td_text + ' ')
                # 寻找下载链接
                dl_url = td_info.find('a', attrs={'class': 'briefDl_D'})
                # 寻找详情链接
                dt_url = td_info.find('a', attrs={'class': 'fz14'})
                # 排除不是所需要的列
                if dt_url:
                    detail_url = dt_url.attrs['href']
                if dl_url:
                    download_url = dl_url.attrs['href']
            # 将每一篇文献的信息分组
            single_refence_list = tr_text.split('@')
            #print(single_refence_list)
            #self.download_refence(download_url, single_refence_list)
            self.download_url = DOWNLOAD_URL + re.sub(r'../', '', download_url)

            # 是否开启详情页数据抓取

            if config.crawl_isdetail == '1':
                #time.sleep(config.crawl_stepWaitTime)
                page_detail.get_detail_page(self.session, self.get_result_url,
                                            detail_url, single_refence_list,
                                            self.download_url, self.filename)
            # 在每一行结束后输入一个空行
            #with open('data/ReferenceList.txt', 'a', encoding='utf-8') as file:
            #    file.write('\n')
        # download_page_left为剩余等待遍历页面
        if download_page_left > 1:
            self.cur_page_num += 1
            self.get_another_page(download_page_left)

2)get_detail_page为获取详情内容,即 get_detail_page 中我们通过 name 和 class 获取页面中的信息,之后利用 xlwt 包将内容保存到本地。

get_detail_page 局部代码如下:

def __init__(self):
        # count用于计数excel行
        self.excel = xlwt.Workbook(encoding='utf8')
        self.sheet = self.excel.add_sheet('文献列表', True)
        self.set_style()
        self.sheet.write(0,0,'序号',self.basic_style)
        self.sheet.write(0, 1, '题名',self.basic_style)
        self.sheet.write(0, 2, '作者',self.basic_style)
        self.sheet.write(0, 3, '单位',self.basic_style)
        self.sheet.write(0, 4, '关键字',self.basic_style)
        self.sheet.write(0, 5, '摘要',self.basic_style)
        #新增-基金和总页数
        self.sheet.write(0, 6, '基金',self.basic_style)
        self.sheet.write(0, 7, '总页数',self.basic_style)
        self.sheet.write(0, 8, '来源',self.basic_style)
        self.sheet.write(0, 9, '发表时间',self.basic_style)
        self.sheet.write(0, 10, '数据库',self.basic_style)
        #新增-被引和下载
        self.sheet.write(0, 11, '被引',self.basic_style)
        self.sheet.write(0, 12, '下载',self.basic_style)
        #if config.crawl_isDownLoadLink=='1':
        #    self.sheet.write(0, 9, '下载地址',self.basic_style)


        # 生成userKey,服务器不做验证
        self.cnkiUserKey=self.set_new_guid()


    def get_detail_page(self, session, result_url, page_url,
                        single_refence_list, download_url, filename):
        '''
        发送三次请求
        前两次服务器注册 最后一次正式跳转
        '''
        # 这个header必须设置
        HEADER['Referer'] = result_url
        self.single_refence_list=single_refence_list
        self.session = session
        self.session.cookies.set('cnkiUserKey', self.cnkiUserKey)
        self.download_url=download_url
        cur_url_pattern_compile = re.compile(
            r'.*?FileName=(.*?)&.*?DbCode=(.*?)&')
        cur_url_set=re.search(cur_url_pattern_compile,page_url)
        # 前两次请求需要的验证参数
        params = {
            'curUrl':'detail.aspx?dbCode=' + cur_url_set.group(2) + '&fileName='+cur_url_set.group(1),
            'referUrl': result_url+'#J_ORDER&',
            'cnkiUserKey': self.session.cookies['cnkiUserKey'],
            'action': 'file',
            'userName': '',
            'td': '1544605318654'
        }
        # 首先向服务器发送两次预请求
        self.session.get(
            'http://i.shufang.cnki.net/KRS/KRSWriteHandler.ashx',
            headers=HEADER,
            params=params)
        #self.session.get(
        #    'http://kns.cnki.net/KRS/KRSWriteHandler.ashx',
        #    headers=HEADER,
        #    params=params)
        page_url = 'http://kns.cnki.net' + page_url
        get_res=self.session.get(page_url,headers=HEADER)
        #gbk_code = get_res.text.encode('GBK', 'ignore').decode('GBK')
        #with open('test.txt','w') as f:
        #    f.write(gbk_code)
        self.pars_page(get_res.text)
        filename_xls = 'data/{}.xls'.format(filename)
        #self.excel.save('data/CNKI.xls')
        self.excel.save(filename_xls)

    def pars_page(self,detail_page):
        '''
        解析页面信息
        '''
        soup=BeautifulSoup(detail_page,'lxml')
        # 获取作者单位信息
        orgn_list=soup.find(name='div', class_='orgn').find_all('a')
        self.orgn=''
        if len(orgn_list)==0:
            self.orgn=''
            #self.orgn='无单位来源'
        else:
            for o in orgn_list:
                self.orgn+=o.string+';'
        # 获取摘要
        self.abstract=''
        try:
            abstract_list = soup.find(name='span', id='ChDivSummary').strings
            for a in abstract_list:
                self.abstract+=a
        except:
            pass
        # 获取关键词
        self.keywords=''
        try:
            keywords_list = soup.find(name='label', id='catalog_KEYWORD').next_siblings
            for k_l in keywords_list:
                # 去除关键词中的空格,换行
                for k in k_l.stripped_strings:
                    self.keywords+=k

        except:
            #self.keywords='无关键词'
            pass
        #新增-获取基金
        self.fund = ''
        try:
            fund_list = soup.find(name = 'label', id = 'catalog_FUND').next_siblings
            for f_l in fund_list:
                #print('f_l',f_l)
                self.fund += f_l.string.strip().replace(';', ';')
        except:
            pass
        #print('fund', self.fund)
        #新增-获取总页码
        self.total_page = ''
        self.total_page = str(soup.find('div','total')('span')[2].b.string)
        #print('total_page',self.total_page)
        self.wtire_excel()

    def create_list(self):
        '''
        整理excel每一行的数据
        #(以前的为)序号 题名 作者 单位 关键字 摘要  来源 发表时间 数据库
                    序号 题名 作者 单位 关键字 摘要 基金 总页码 来源 发表时间 数据库 被引 下载
        '''
        #single_reference_list为搜索界面的数据
        self.reference_list = []
        for i in range(0,3):
            self.reference_list.append(self.single_refence_list[i])
        self.reference_list.append(self.orgn)
        self.reference_list.append(self.keywords)
        self.reference_list.append(self.abstract)
        self.reference_list.append(self.fund)
        self.reference_list.append(self.total_page)
        for i in range(3,8):
            self.reference_list.append(self.single_refence_list[i])

第三,当捕捉完当前页面内容后,我们需要捕捉下一个页面内容,即再一次对网站发送请求,代码如下:

    def get_another_page(self, download_page_left):
        '''
        请求其他页面和请求第一个页面形式不同
        重新构造请求
        '''
        #time.sleep(config.crawl_stepWaitTime)
        curpage_pattern_compile = re.compile(r'.*?curpage=(\d+).*?')
        self.get_result_url = CHANGE_PAGE_URL + re.sub(
            curpage_pattern_compile, '?curpage=' + str(self.cur_page_num),
            self.change_page_url)
        get_res = self.session.get(self.get_result_url, headers=HEADER)
        download_page_left -= 1
        self.parse_page(download_page_left, get_res.text)

第四,根据自定义的时间范围,我们可以获取在这个区间内的所有论文信息,代码如下:

def main(user_input):
    time.perf_counter()
    search = SearchTools()
    search.search_reference(user_input)
    print('--------------------------')
    print('共运行:'+s2h(time.perf_counter()))

time_range = list(range(2000,2018))
for index,i in enumerate(time_range):
    user_input = {'magazine_value1':'经济研究'}
    user_input['publishdate_from'] = '{}-01-01'.format(str(i))
    user_input['publishdate_to'] = '{}-12-31'.format(str(i))
    filename = filename = '{}({}~{})'.format(user_input['magazine_value1'], user_input['publishdate_from'], user_input['publishdate_to'])
    print('现爬取年份为',i,'爬取区间为','{}~{}'.format(time_range[0],time_range[-1]-1))
    print(filename)
    if index != 0:
        print('停止3秒')
        time.sleep(3)
    main(user_input)
    print('爬取结束')

爬取结果如下:

爬取原始结果
爬取原始结果

4. 数据简析

爬取数据去重后,得到 3430 条数据。根据爬取到的信息,我们需要对数据进行预处理,以有无关键词作为衡量是否为学术文章的标准。

df_keyword = df[df['关键字'].notnull()]
df_keyword.loc[:,'年份'] = df_keyword.loc[:,'发表时间'].str[:4]
df_keyword = df_keyword.set_index(['年份'])
df_keyword.head()

之后我们对数据进行简单的统计分析。

4.1 摘要字数变动情况分析

使用正则表达式来计算摘要汉字个数,分析摘要字数变化趋势,趋势图与代码如下:

df1_keyword = df_keyword.copy()
df1_keyword.loc[:,'count'] = 1
df1_keyword.loc[:,'题名字数'] = df1_keyword.loc[:,'题名'].str.count(r'[\u4E00-\u9FA5]')
df1_keyword.loc[:,'作者人数'] = df1_keyword.loc[:,'作者'].str.count(';') + df1_keyword.loc[:,'作者'].str.count(',') + 1
df1_keyword.loc[:,'摘要字数'] = df1_keyword.loc[:,'摘要'].str.count(r'[\u4E00-\u9FA5]')
df1_keyword.loc[:,'摘要句数'] = df1_keyword.loc[:,'摘要'].str.count('。')
df1_keyword.loc[:,'基金数'] = df1_keyword.loc[:,'基金'].str.count(';')
df1_keyword['是否有基金'] = df1_keyword.loc[:,'基金'].notnull()
#df1_keyword['是否有基金'] = df1_keyword[df1_keyword['基金'].notnull()]
df1_keyword.head()

f, axes = plt.subplots(1, 1, sharey=True, figsize=(12, 8))
#sns.boxplot(x="day", y="tip", data=tips, ax=axes[0])
sns.swarmplot(x = df1_keyword.index, y = df1_keyword.loc[:,'摘要字数'], orient='v', size = 5, ax=axes)

摘要字数趋势图:

摘要数字趋势图
摘要数字趋势图

从结果来看,2000 年以来,在《经济研究》文献中作者写作的摘要字数逐年攀升,学者对问题的解析和思考日渐细致。

4.2 下载与被引关系分析

为研究被引和下载量的关系,我们利用 seaborn 画出如下图:

x = df1_keyword.loc[:,'下载']
y = df1_keyword.loc[:,'被引']
sns.jointplot(x, y, color="#4CB391",xlim = (0,20000),ylim = (0,1000),kind="reg" )

下载与被引线性拟合图:

下载与被引关系
下载与被引关系

这里对下载与被引数使用 python 语言进行一次简单的线性回归(结果并非十分严谨准确),可以在一定程度上认为二者呈现正相关关系。

4.3 发文作者情况

进一步我们分析相关领域的主要作者,对全部文献进行统计:

all_author_raw = list(df1_keyword.loc[:,'作者'])
all_author = []
for i in all_author_raw:
    try:
        one_paper_author_list = i.replace(',',';').split(';')
        for k in one_paper_author_list:
            all_author.append(k)
    except:
        all_author.append(i)
#len(all_author)
counts = {}
for author in all_author:
    counts[author] = counts.get(author,0) + 1
counts.pop('')
items = list(counts.items())
items.sort(key = lambda x:x[1], reverse = True)
print('出现次数排名前十的作者')
items[:10]

我们得出出现次数前 10 位的作者如下:

发文前十作者排名
发文前十作者排名

4.4 发文单位情况

对发文的大学与科研机构进行统计分析。分析代码与结果如下:

all_organ_raw = list(df1_keyword.loc[:,'单位'])
all_organ_raw1 = []
for i in all_organ_raw:
    try:
        one_paper_organ_list = i.replace(',',';').split(';')
        for k in one_paper_organ_list:
            all_organ_raw1.append(k)
    except:
        all_organ_raw1.append(i)
#all_organ_raw1
all_organ = []
for i in all_organ_raw1:
    try:
        all_organ.append(re.match(r'[\u4E00-\u9FA5]+',i).group(0))
    except:
        pass
for index,organ in enumerate(all_organ):
    if organ == '邮政编码':
        all_organ.pop(index)
len(all_organ)

all_univ = []
for i in all_organ:
    try:
        s = i.index('大学')+2
        all_univ.append(i[:s])
    except:
        pass
#all_univ
print('大学总出现次数(重复计算)',len(all_univ))
count = {}
for i in all_univ:
    count[i] = count.get(i,0)+1
items = list(count.items())
items.sort(key = lambda x:x[1], reverse = True)
x = 20
rank = pd.DataFrame(items[:x], index = list(range(1,x+1)))
rank.index.name = '排名'
rank.columns = ['大学','次数']
rank

count = {}
for i in all_organ:
    count[i] = count.get(i,0)+1
items = list(count.items())
items.sort(key = lambda x:x[1], reverse = True)
#想要前x位数据
x = 20
want_list = items[:x]
name  = [want_list[i][0] for i in range(x)]
num  = [want_list[i][1] for i in range(x)]
organ_rank = pd.DataFrame(want_list,index = list(range(1,x+1)))
organ_rank.index.name = '排名'
organ_rank.columns = ['机构','次数']
organ_rank

发文学校排名结果:

发文学校排名
发文学校排名

可以看到北京大学以 402 发文数量遥遥领先,中国人民大学以 271 篇位居第二,上海财经大学、复旦大学、厦门大学与中山大学旗鼓相当处于 3-6 位。

发文机构排名结果:

文学机构排名
文学机构排名

具体到发文机构(学院),中国社会科学院经济研究所以 140 篇位居第一,北大光华学院紧跟其后。

对比上述两组结果,我们观察到华中科技大学经济学院表现亮眼,其在《经济研究》中 40 篇发文数量与上海财经大学经济学院仅差 1 篇,超过中山管院、厦大管院、山大经院等知名院校。

4.5 关键词统计

此外,我们对文章的关键词进行按年统计分析,提取"政策","税收","制度","增长","企业"五个关键词观察其每年使用次数的走势,代码如下:

zhaiyao_df = pd.concat(zhaiyao_lcut)
zhaiyao_df.columns = ['关键词','词频','年份']
zhaiyao_df =zhaiyao_df.set_index(['年份','关键词'])
zhaiyao_df.head()
zhaiyao_df.sum(level = '年份').T
cipin = zhaiyao_df.sum(level = '关键词')
#注意此处与列表sort的区别,列表中关键词为key,倒转为reverse = True
cipin = cipin.sort_values(by = '词频', ascending = False)
#查看前10词频排名
cipin.head(10).T
#查看单个词汇是否出现,以及总的出现频次
cipin.loc['价值链']
zhaiyao_df_w = zhaiyao_df.unstack('关键词')
zhaiyao_df_w.info()
zhaiyao_df_w1 = zhaiyao_df_w.copy()
zhaiyao_df_w1.columns = zhaiyao_df_w.columns.swaplevel(0,1)
want_keyword = ['政策','税收','制度','增长','企业']
#注意index不能用:,而要用slice(None)替代
data = zhaiyao_df_w1.loc[:,(want_keyword,slice(None))].fillna(0)
data
ax = sns.lineplot(data  = data)
a = ax.set_xticklabels(data.index,rotation=60)

提取的五个关键词走势图如下:

关键词词频走势图
关键词词频走势图

可以看出,近年来对企业、税收以及政策问题的研究文献越来越多,统计结果意味着:一方面微观企业部门依然是学界密切关注的话题,另一方面对我国经济政策,包括对税收政策的讨论,持续升温。

5. 总结

本文主要介绍了利用 python 爬虫对知网文献信息进行爬取,并利用相关技术对爬取的信息进行简单的分析。而更多的 Python 爬虫方法则需要我们在实践中不断学习和进步。

通过阅读本文,可以掌握如下信息:

  1. 了解 Python 爬虫的一般流程和思路,掌握模拟真人访问、内容捕捉和翻页的基本用法。

  2. 了解使用 Python 进行基本数据内容提取、分析的用法。

6. 相关资料

  • 北京理工大学,嵩天,MOOC《Python 网络爬虫与信息提取》,课程链接:https://www.icourse163.org/learn/BIT-1001870001?tid=1206093223#/learn/announce
  • 本文爬虫数据及 py 文件百度云地址:
    • 链接: https://pan.baidu.com/s/1Onrpud-mpWAp84F390_vdg
    • 提取码: 271g

相关课程

连享会-直播课 上线了!
http://lianxh.duanshu.com

免费公开课:


课程一览

支持回看,所有课程可以随时购买观看。

专题 嘉宾 直播/回看视频
最新专题 DSGE, 因果推断, 空间计量等
Stata数据清洗 游万海 直播, 2 小时,已上线
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]

Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。


关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。直播间 有很多视频课程,可以随时观看。
  • 连享会-主页知乎专栏,300+ 推文,实证分析不再抓狂。
  • 公众号推文分类: 计量专题 | 分类推文 | 资源工具。推文分成 内生性 | 空间计量 | 时序面板 | 结果输出 | 交乘调节 五类,主流方法介绍一目了然:DID, RDD, IV, GMM, FE, Probit 等。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会主页  lianxh.cn
连享会主页 lianxh.cn

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会学习群-常见问题解答汇总:
https://gitee.com/arlionn/WD