大数跨境
0
0

Python实现“维基百科六度分隔理论“之基础爬虫

Python实现“维基百科六度分隔理论“之基础爬虫 CDA数据分析师
2017-04-01
1
导读:如何使用MySQL进行数据存储?简单易学三分钟搞定!
戳蓝字关注我们!

作者 Airy

本文转自 AiryData,转载需授权


前  言


上一篇我们学习了数据采集中一个页面跳转到另一个页面的简单爬虫,虽然获取了这些链接数据,但是由于链接数目太多,不好查看,所以我们要想办法存储起来。


这里使用 MySQL 进行数据存储,关于 MySQL 的使用,以及使用 Python 操作 MySQL,在我之前的文章中都有提到。


MySQL 中的“六度空间游戏”


前面我们已经建立了网络爬虫来采集网页,今天我们要把采集到的信息用数据库存储起来,方便后面进行数据分析。MySQL 基础知识,在我之前的文章中说的已经很多了,这里不再赘述,默认同学已经了解了 MySQL。


为了确定最合理的信息存储方式,我们要先想一下我们的处理规则。一个链接可以轻易地把页面 A 连接到页面 B,就像百度搜索,搜出来的结果就可以链接到我的网站。同样也可以把页面 B 连接到页面 A,我只需要把百度的网址插入到这篇文章就可以,不过这就是另一条链接了。所以我们可以这样识别一个链接:即“页面A存在一个链接,可以连接到页面B” 。也就是说,INSERT INTO links(fromPageId, toPageId) VALUES(A, B) ;其中 A 和 B 分别表示页面的 ID 号。


这里我们设计一个带有两张数据表的数据库来分别存储页面和链接,两张表都带有创建时间和独立的 ID 号,代码如下:


CREATE TABLE `wiki`.`pages`(
    `id` INT NOT NULL AUTO_INCREMENT COMMENT '自增id,主键',
    `url` VARCHAR(255) NOT NULL,
    `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY(`id`)

 
  );

CREATE TABLE `wiki`.`links`(
    `id` INT NOT NULL AUTO_INCREMENT COMMENT '自增id,主键',
    `fromPageId` INT NULL,
    `toPageId` INT NULL,
    `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY(`id`)
    );


需要注意的是,这里我没有创建标题字段,因为,一般情况下,只有点击链接进去才能看到网页标题,不过对于维基百科来说还好,wiki 的词条链接和对应的页面标题直接转换一下就可以,例如 en.wikipedia.org/wiki/Monty_Python 的后面就是页面标题 Monty Python。


下面我们来写一下把“贝肯数”(一个页面与凯文·贝肯词条页面的链接数)不超过 6 的维基百科页面存储起来。


from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import pymysql
#连接时,密码要换成自己的
conn = pymysql.connect(host = '127.0.0.1', port = 3306, user = 'root', passwd = 'xxxxxxxx', db = 'wiki', charset = 'utf8mb4')

cur = conn.cursor()
#cur.execute("USE wiki")

def insertPageIfNotExists(url):
    cur.execute("SELECT * FROM pages WHERE url = %s", (url))
    if cur.rowcount == 0:
        cur.execute("INSERT INTO pages (url) VALUES (%s)", (url))
        conn.commit()
        return cur.lastrowid
    else:
        return cur.fetchone()[0]

def insertLink(fromPageId, toPageId):
    cur.execute("SELECT * FROM links WHERE fromPageId = %s AND toPageId = %s",(int(fromPageId), int(toPageId)))
    if cur.rowcount == 0:
        cur.execute("INSERT INTO links (fromPageId, toPageId)  VALUES(%s, %s)",(int(fromPageId), int(toPageId)))
        conn.commit()

pages = set()
def getLinks(pageUrl, recursionLevel):
    global pages
    if recursionLevel > 4:
        return;
    pageId = insertPageIfNotExists(pageUrl)
    html = urlopen("http://en.wikipedia.org" + pageUrl)
    soup = BeautifulSoup(html, "lxml")
    for link in soup.findAll("a", href = re.compile("^(/wiki/)((?!:).)*$")):
        insertLink(pageId, insertPageIfNotExists(link.attrs['href']))
        if link.attrs['href'] not in pages:
            #遇到新页面,加入集合并搜索里面的词条链接
            newPage = link.attrs['href']
            pages.add(newPage)
            getLinks(newPage, recursionLevel + 1)

getLinks("/wiki/Kevin_Bacon", 0)
cur.close()
conn.close()


上面的代码就能获取我们需要的链接,但是需要注意,由于维基百科里面的链接很多,所以这个程序很费时间,为了节省时间,运行几分钟就可以中断了,我运行了一两分钟,数据已经有两千多条了,同时维基百科服务器也会拒绝程序请求。但是这些数据已经够我们在后面进行链接路径问题数据分析了。


小  结


这里我们重新复习了一下 pymysql 库的用法,加深我们对之前知识的了解,提高问题解决能力,数据库使我们存储数据必不可少的工具,希望大家都能学一些基础知识,具体内容可以看我前段时间发布的 MySQL 基础教程,后面还有高级内容哦。


希望通过上面的内容能帮助大家。如果你有什么好的意见,建议,或者有不同的看法,我都希望你留言和我们进行交流、讨论。



推荐阅读

函数 | 这8组Excel函数,帮您解决工作中80%的难题

国外公司是如何挖掘社交媒体数据的?

大数据舆情情感分析,如何提取情感并使用什么样的工具?(贴情感标签)

【干货】Pandas速查手册中文

四步搭建企业服务数据分析体系

【进阶】代码这样写不止于优雅( Python 版)

【干货】找不到适合自己的编程书?我自己动手写了一个热门编程书搜索网站(附PDF书单)

数据分析入门案例:泰坦尼克号幸存率研究

玩转Excel动态图表,必须学会的3个套路

盘点 | 2017 最“热”门的十大数据技术

还留在北京的,都是没有退路的

数据分析听着学:10个不可错过的数据相关优质播客

【进阶】Excel 数据透视表,10 个不得不说的秘密

数据科学家VS数据工程师,真的是一山不容二虎?

专访 ▏陈春宝——大数据应该如何更接地气儿?

【扫盲】如何区分人工智能,机器学习和深度学习


【声明】内容源于网络
0
0
CDA数据分析师
🌸全国30万数据分析从业人员,有10万在CDA数据分析师 🌺CDA会员俱乐部有1000个数据库,成为持证人即可获得相关数据信息 🌹未来两样东西最有价值:一个是数据,一个是GPU
内容 9451
粉丝 0
CDA数据分析师 🌸全国30万数据分析从业人员,有10万在CDA数据分析师 🌺CDA会员俱乐部有1000个数据库,成为持证人即可获得相关数据信息 🌹未来两样东西最有价值:一个是数据,一个是GPU
总阅读459
粉丝0
内容9.5k