美文网首页Python学习爬不动的毛毛虫
爬取国内创业公司、投资机构、独角兽公司信息

爬取国内创业公司、投资机构、独角兽公司信息

作者: 天善智能 | 来源:发表于2019-02-11 14:49 被阅读73次

    欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

    对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

    作者:  苏克1900

    公众号:第2大脑

    摘要: 之前爬的网站都是不需要登录就可以爬取的,但还有很多网站的内容需要先登录才能爬,比如桔子网、豆瓣、知乎等。这时采用之前的方法就不行了,需要先登录再去爬。本文以桔子网为例,介绍模拟登录方法,然后爬取该网站数据库中的数据信息,并保存到 MongoDB 数据库中。

    1. 网站介绍

    网址:https://www.itjuzi.com/

    对于创投圈的人来说,国内的桔子和国外的 Crunchbase应该算是必备网站。今天,我们要说的就是前者,这个网站提供了很多有价值的信息。

    信息的价值体现在哪里呢,举个简单的例子。你运营了一个不错的公众号,有着 10 万粉丝群,这时候你想找投资继续做大,但你不知道该到哪里去找投资。这时候你偶然发现了这个网站,在网站上你看到了同领域的大 V 号信息,他们得到了好几家公司上千万的投资。你看着心生羡慕,也跃跃欲试。于是,你经过综合对比分析,对自己公众号估值 200 万,然后就去找投资大 V 号的那几家公司洽谈。由于目的性明确,准备也充分,你很快就得到了融资。

    这个例子中,桔子网提供了创业公司(运营公众号也是创业)融资金额和投资机构等相关宝贵的信息。当然,这只是非常小的一点价值,该网站数据库提供了自 2000 年以来的海量数据,包括:超过11 万家的创业公司、6 万多条投融资信息、7 千多家投资机构以及其他数据,可以说是非常全了。这些数据的背后蕴含着大量有价值的信息。

    接下来,本文尝试爬取该网站数据库的信息,之后做一些数据分析,尝试找到一些有意思的信息。

    主要内容:

    模拟登录

    分析 Ajax 然后抓取

    存储到 MongoDB 数据库

    导出 csv

    数据分析(后期)

    2. 模拟登录

    2.1. Session 和 Cookies

    观察这个网站,是需要先登录才能看到数据信息的,但是好在不用输验证码。我们需要利用账号和密码,然后实现模拟登录。

    模拟登录的方法有好几种,比如 Post 直接提交账号、先登录获取 Cookies 再直接请求、Selenium 模拟登录等。其中:

    Post 方法需要在后台获取登录的 url,填写表单参数然后再请求,比较麻烦;

    直接复制 Cookies 的方法就是先登录账号,复制出 Cookies 并添加到 Headers 中,再用requests.get 方法提交请求,这种方法最为方便;

    Selenium 模拟登录方法是直接输入账号、密码,也比较方便,但速度会有点慢。

    之后,会单独介绍几种方法的具体实现的步骤。这里,我们就先采用第二种方法。

    首先,需要先了解两个知识点:Session 和 Cookies。

    Session 在服务端,也就是网站的服务器,用来保存用户的会话信息,Cookies 在客户端,也可以理解为浏览器端,有了 Cookies,浏览器在下次访问网页时会自动附带上它发送给服务器,服务器通过识别 Cookies 并鉴定出是哪个用户,然后再判断用户是否是登录状态,然后返回对应的 Response。所以我们可以理解为 Cookies 里面保存了登录的凭证,有了它我们只需要在下次请求携带 Cookies 发送 Request 而不必重新输入用户名、密码等信息重新登录了。

    因此在爬虫中,有时候处理需要登录才能访问的页面时,我们一般会直接将登录成功后获取的 Cookies 放在 Request Headers 里面直接请求。

    更多知识,可以参考崔庆才大神的文章:

    https://germey.gitbooks.io/python3webspider/content/2.4-Session%E5%92%8CCookies.html

    在了解 Cookies 知识后,我们就可以进入正题了。

    2.2. Requests 请求登录

    首先,利用已有的账号和密码,登录进网站主页,然后右键-检查,打开第一个 www.itjuzi.com请求:

    向下拉到 Requests Headers 选项,可以看到有很多字段信息,这些信息之后我们都要添加到 Get 请求中去。

    定位到下方的 Cookie 字段,可以看到有很多 Cookie 值和名称,这是在登录后自动产生的。我们将整个 Cookies 复制 Request Headers 里,然后请求网页就可以顺利登陆然后爬取。如果不加 Cookies,那么就卡在登录界面,也就无法进行后面的爬取,所以 Cookies 很重要,需要把它放到 Request Headers 里去。

    下面,我们按照 json 格式开始构造 Request Headers。这里推荐一个好用的网站,可以帮我们自动构造 Request Headers:https://curl.trillworks.com/

    使用方法也很简单,右键复制cURL链接到这个网页中。

    将 cURL 复制到左边选框,默认选择语言为 Python,然后右侧就会自动构造后 requests 请求,包括 headers,复制下来直接可以用。登录好以后,我们就转到投融资速递网页中(url:http://radar.itjuzi.com/investevent),然后就可以获取该页面网页内容了。代码如下:

    1importrequests

    2headers = {

    3'Connection':'keep-alive',

    4'Cache-Control':'max-age=0',

    5'Upgrade-Insecure-Requests':'1',

    6'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36',

    7'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',

    8'DNT':'1',

    9'Referer':'http://radar.itjuzi.com/investevent',

    10'Accept-Encoding':'gzip, deflate, br',

    11'Accept-Language':'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',

    12'If-None-Match':'W/^\\^5bc7df15-19cdc^\\^',

    13'If-Modified-Since':'Thu, 18 Oct 2018 01:17:09 GMT',

    14# 主页cookie

    15'Cookie':'你的cookie',

    16}

    17

    18url ='http://radar.itjuzi.com/investevent'# 投融资信息

    19s = requests.Session()

    20response = s.get(url,headers = headers)

    21print(response.status_code)

    22print(response.text)

    结果如下:

    可以看到,添加 Cookie 后,我们请求投融资信息网页就成功了。这里如果不加 Cookie 的结果就什么也得不到:

    好,这样就算成功登录了。但是整个 headers 请求头的参数太多,是否一定需要带这么多参数呢? 这里就去尝试看哪些参数是请求一定要的,哪些则是不用的,不用的可以去掉以精简代码。经过尝试,仅需要下面三个参数就能请求成功。

    1headers = {

    2'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'

    3'X-Requested-With':'XMLHttpRequest',

    4# 主页cookie

    5'Cookie':'复制你的cookie',

    6}

    Tips:当爬取失效的时候需要重新注册帐号,然后生成新的 Cookie。

    如果你没那么多邮箱账号,那么推荐一个可生成随机账号的免费邮箱,用来接收注册激活链接:

    https://10minutemail.net/

    3. 网页爬取分析

    在成功登录以后,我们就可以通过分析网页结构来采取相应的爬取方法。这里,我们将爬取投融资速递、创业公司、投资机构和千里马等几个子板块的数据。首先,以投融资速递信息为例。

    网址:http://radar.itjuzi.com/investevent

    3.1. 分析网页

    可以看到,投融资事件信息网页中的数据是表格形式。经尝试点击翻页,发现url不变,可以初步判定网页数据采用 Ajax 形式呈现。切换到后台,点击翻页可以发现出现有规律的 info?locatiop 开头的请求,页数随 page 参数而发生规律的变化。

    点击请求查分别查看 Response 和 Preview,发现表格数据是 json 格式,这就太好了。因为 json 格式的数据非常整齐也很容易抓取。上一篇文章,我们正好解决了 json 格式数据的处理方法,如果不太熟悉可以回顾一下:

    https://www.makcyun.top/web_scraping_withpython6.html

    接着,我们就可以通过构造 url 参数,然后用 Get 请求就可以获取网页中的表格数据,最后再加个循环,就可以爬取多页数据了。

    3.2. 构造 url

    下面,我们来构造一下 url,切换到 Headers 选项卡,拉到最底部可以看到 url 需带的请求参数。这里有三项,很好理解。location:in,表示国内数据; orderby:def,表示默认排序;page:1,表示第一页。所以,只需要改变 page 参数就可以查看其他页的结果,非常简单。

    这里,如果我们对表格进行筛选,比如行业选择教育、时间选择 2018 年,那么相应的请求参数也会增加。通过构造参数就可以爬取指定的数据,这样就不用全部爬下来了,也对网站友好点。

    3.3. 爬取数据

    到这儿,我们就可以直接开始爬了。可以使用函数,也可以用定义类(Class)的方法。考虑到,Python 是一种面向对象的编程,类(Class)是面向对象最重要的概念之一,运用类的思想编程非常重要。所以,这里我们尝试采用类的方法来实现爬虫。

    1importrequests

    2importpymongo

    3importrandom

    4importtime

    5importjson

    6importpandasaspd

    7fromfake_useragentimportUserAgent

    8ua = UserAgent()

    9

    10classITjuzi(object):

    11def__init__(self):

    12self.headers = {

    13'User-Agent': ua.random,

    14'X-Requested-With':'XMLHttpRequest',

    15'Cookie':'你的cookie',

    16}

    17self.url ='http://radar.itjuzi.com/investevent/info?'# investevent

    18self.session = requests.Session()

    19

    20defget_table(self, page):

    21"""

    221 获取投融资事件数据

    23"""

    24params = {# invsestevent

    25'location':'in',

    26'orderby':'def',

    27'page': page,

    28'date':2018# 年份

    29}

    30response = self.session.get(

    31self.url, params=params, headers=self.headers).json()

    32print(response)

    33# self.save_to_mongo(response)

    34

    35if__name__ =='__main__':

    36spider = itjuzi()

    37spider.get_table(1)

    如果你之前一直是用 Def 函数的写法,而没有接触过 Class 类的写法,可能会看地比较别扭,我之前就是这样的,搞不懂为什么要有 self、为什么用__init__。这种思维的转变可以通过看教程和别人写的实际案例去揣摩。这里,我先略过,之后会单独介绍。

    简单解释一下上面代码的意思。首先定义了一个类(class),类名是 ITjuzi,类名通常是大写开头的单词。后面的 (object) 表示该类是从哪个类继承下来的,这个可以暂时不用管,填上就可以。然后定义了一个特殊的__init__方法,__init__方法的第一个参数永远是 self,之后是其他想要设置的属性参数。在这个方法里可以绑定些确定而且必须的属性,比如 headers、url 等。

    在 headers 里面,User-Agent 没有使用固定的 UA,而是借助 fake_useragent包 生成随机的 UA:ua.random。因为,这个网站做了一定的反爬措施,这样可以起到一定的反爬效果,后续我们会再说到。接着,定义了一个 get_table() 函数,这个函数和普通函数没有什么区别,除了第一个参数永远是实例变量 self。在 session.get()方法中传入 url、请求参数和 headers,请求网页并指定获取的数据类型为 json 格式,然后就可以顺利输出 2018 年投融资信息的第 1 页数据:

    3.4. 存储到 MongoDB

    数据爬取下来了,那么我们放到哪里呢?可以选择存储到 csv 中,但 json 数据中存在多层嵌套,csv 不能够直观展现。这里,我们可以尝试之前没有用过的 MongoDB 数据库,当作练习。另外,数据存储到该数据库中,后期也可以导出 csv,一举两得。

    关于 MongoDB 的安装与基本使用,可以参考下面这两篇教程,之后我也会单独再写一下:

    安装

    https://germey.gitbooks.io/python3webspider/content/1.4.2-MongoDB%E7%9A%84%E5%AE%89%E8%A3%85.html

    使用

    https://germey.gitbooks.io/python3webspider/content/5.3.1-MongoDB%E5%AD%98%E5%82%A8.html

    可视化工具可采用 Robo 3T (之前叫 RoboMongo)

    https://www.mongodb.com/

    下面我们就将上面返回的 json 数据,存储到 MongoDB 中去:

    1importpymongo

    2importnumpyasnp

    3# mongodb数据库初始化

    4client = pymongo.MongoClient('localhost',27017)

    5# 指定数据库

    6db = client.ITjuzi

    7# 指定集合,类似于mysql中的表

    8mongo_collection1 = db.itjuzi_investevent

    9

    10defsave_to_mongo(self, response):

    11try:

    12data = response['data']['rows']# dict可以连续选取字典层内的内容

    13df = pd.DataFrame(data)

    14table = json.loads(df.T.to_json()).values()

    15ifmongo_collection1.insert_many(table):# investment

    16print('存储到mongodb成功')

    17sleep = np.random.randint(3,7)

    18time.sleep(sleep)

    19exceptException:

    20print('存储到mongodb失败')

    21defspider_itjuzi(self, start_page, end_page):

    22forpageinrange(start_page, end_page):

    23print('下载第%s页:'% (page))

    24self.get_table(page)

    25print('下载完成')

    26

    27if__name__ =='__main__':

    28spider = ITjuzi()

    29spider.spider_itjuzi(1,2)

    这里,安装好 MongoingDB 数据库、Robo 3T 和 pymongo 库后,我们就可以开始使用了。

    首先,对数据库进行初始化,然后指定(如果没有则生成)数据将要存放的数据库和集合名称。接着,定义了save_to_mongo 函数。由于表格里面的数据存储在键为 rows 的 value 值中,可使用 response['data']['rows'] 来获取到 json 里面的嵌套数据,然后转为 DataFrame。DataFrame 存储 MongoDB 参考了 stackoverflow 上面的一个答案:json.loads(df.T.to_json()).values()

    然后,使用 mongo_collection1.insert_many(table) 方法将数据插入到 mongo_collection1,也就是 itjuzi_investevent 集合中。爬取完一页数据后,设置随机延时 3-6 s,避免爬取太频繁,这也能起到一定的反爬作用。

    最后,我们定义一个分页循环爬取函数 spider_itjuzi,利用 for 循环设置爬取起始页数就可以了,爬取结果如下:

    打开 Robo 3T,可以看到数据成功存储到 MongoDB 中了:

    好,以上,我们就基本上完成了 2018 年投融资信息数据表的爬取,如果你想爬其他年份或者更多页的数据,更改相应的参数即可。

    3.5. 导出到 csv

    数据存好后,如果还不太熟悉 MongoDB 的对数据的操作,那么我们可以将数据导出为 csv,在 excel 中操作。MongoDB不能直接导出 csv,但操作起来也不麻烦,利用mongoexport命令,几行代码就可以输出 csv。

    mongoexport导出 csv 的方法:

    https://docs.mongodb.com/manual/reference/program/mongoexport/#mongoexport-fields-example

    首先,运行 cmd,切换路径到 MongoDB 安装文件夹中的 bin 目录下,我这里是:

    1cd C:\Program Files\MongoDB\Server\4.0\bin

    接着,在桌面新建一个txt文件,命名为fields,在里面输入我们需要输出的表格列名,如下所示:

    然后,利用mongoexport命令,按照:表格所在的数据库、集合、输出格式、导出列名文件位置和输出文件名的格式,编写好命令并运行就可以导出了:

    1mongoexport --db ITjuzi --collection itjuzi_investevent --type=csv --fieldFile C:\Users\sony\Desktop\fields.txt --out C:\Users\sony\Desktop\investevent.csv

    cmd 命令:

    导出 csv 结果如下:

    Tips:直接用 excel 打开可能会是乱码,需先用 Notepad++ 转换为 UTF-8 编码,然后 excel 再打开就正常了。

    以上,我们就完成了整个数据表的爬取。

    3.6. 完整代码

    下面,可以再尝试爬取创业公司、投资机构和千里马的数据。他们的数据结构形式是一样的,只需要更换相应的参数就可以了,感兴趣的话可以尝试下。将上面的代码再稍微整理一下,完整代码如下:

     1importrequests

     2importre

     3importpymongo

     4importrandom

     5importtime

     6importjson

     7importrandom

     8importnumpyasnp

     9importcsv

    10importpandasaspd

    11fromfake_useragentimportUserAgent

    12importsocket# 断线重试

    13fromurllib.parseimporturlencode

    14# 随机ua

    15ua = UserAgent()

    16# mongodb数据库初始化

    17client = pymongo.MongoClient('localhost',27017)

    18# 获得数据库

    19db = client.ITjuzi

    20# 获得集合

    21mongo_collection1 = db.itjuzi_investevent

    22mongo_collection2 = db.itjuzi_company

    23mongo_collection3 = db.itjuzi_investment

    24mongo_collection4 = db.itjuzi_horse

    25

    26classitjuzi(object):

    27def__init__(self):

    28

    29self.headers = {

    30'User-Agent': ua.random,

    31'X-Requested-With':'XMLHttpRequest',

    32# 主页cookie

    33'Cookie':'你的cookie',

    34}

    35self.url ='http://radar.itjuzi.com/investevent/info?'# investevent

    36# self.url = 'http://radar.itjuzi.com/company/infonew?'       # company

    37# self.url = 'http://radar.itjuzi.com/investment/info?'       # investment

    38# self.url = 'https://www.itjuzi.com/horse'               # horse

    39self.session = requests.Session()

    40

    41defget_table(self, page):

    42"""

    431 获取投融资事件网页内容

    44"""

    45params = {# 1 invsestevent

    46'location':'in',

    47'orderby':'def',

    48'page': page,

    49'date':2018#年份  

    50}

    51

    52# # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # #

    53# params = {                  # 2 company

    54#     'page': page,

    55#     # 'scope[]': 1,  # 行业 1教育

    56#     'orderby': 'pv',

    57#     'born_year[]': 2018,  # 只能单年,不能多年筛选,会保留最后一个

    58# }

    59# # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # #

    60# params = {                  # 3 investment

    61# 'orderby': 'num',

    62# 'page': page

    63# }

    64# # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # #

    65# params = {                  # 4 horse

    66# }

    67# 可能会遇到请求失败,则设置3次重新请求

    68retrytimes =3

    69whileretrytimes:

    70try:

    71response = self.session.get(

    72self.url, params=params, headers=self.headers,timeout = (5,20)).json()

    73self.save_to_mongo(response)

    74break

    75exceptsocket.timeout:

    76print('下载第{}页,第{}次网页请求超时'.format(page,retrytimes))

    77retrytimes -=1

    78

    79defsave_to_mongo(self, response):

    80try:

    81data = response['data']['rows']# dict可以连续选取字典层内的内容

    82# data =response  # 爬取千里马时需替换为此data

    83df = pd.DataFrame(data)

    84table = json.loads(df.T.to_json()).values()

    85ifmongo_collection1.insert_many(table):# investevent

    86# if mongo_collection2.insert_many(table):    # company

    87# if mongo_collection3.insert_many(table):    # investment

    88# if mongo_collection4.insert_many(table):    # horse 

    89print('存储到mongodb成功')

    90sleep = np.random.randint(3,7)

    91time.sleep(sleep)

    92exceptException:

    93print('存储到mongodb失败')

    94

    95defspider_itjuzi(self, start_page, end_page):

    96forpageinrange(start_page, end_page):

    97print('下载第%s页:'% (page))

    98self.get_table(page)

    99print('下载完成')

    100

    101if__name__ =='__main__':

    102spider = itjuzi()

    103spider.spider_itjuzi(1,2)

    源代码也可以在下面的链接中获取:

    https://github.com/makcyun/web_scraping_with_python

    4. 总结:

    本文以桔子网为例,介绍了需登录网站的爬取方法。即:先模拟登录再爬取数据信息。但是还有一些网站登录时需要输入验证码,这让爬取难度又增加,后期会再进行介绍。

    该网站相比之前的爬虫网站,反爬措施高了很多。本文通过设置随机延时、随机 UserAgent,可一定程度上增加爬虫的稳定性。但是仍然会受到反爬措施的限制,后期可尝试通过设置 IP 代理池进一步提升爬虫效率。

    上面的爬虫程序在爬取过程容易中断,接着再进行爬取即可。但是手动修改非常不方便,也容易造成数据重复爬取或者漏爬。所以,为了更完整地爬取,需增加断点续传的功能。

    补充一下,后期可能会在我的博客中不断更新、补充本文的内容。如想获得更多,可点击阅读原文,或者浏览器打开我的博客链接。

    https://www.makcyun.top

    本文完。

    作者好文推荐:分析了6000款App,竟有这么多佳软神器没用过

    Python爱好者社区历史文章大合集

    Python爱好者社区历史文章列表(每周append更新一次)

    福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

    关注后在公众号内回复“课程”即可获取:

    小编的转行入职数据科学(数据分析挖掘/机器学习方向)【最新免费】

    小编的Python入门免费视频课程!!!

    小编的Python快速上手matplotlib可视化库!!!

    崔老师爬虫实战案例免费学习视频。

    陈老师数据分析报告制作免费学习视频。

    玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。

    相关文章

      网友评论

        本文标题:爬取国内创业公司、投资机构、独角兽公司信息

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