爬取百度百科信息

本文参考链接:
爬百科
安裝Mongodb

具体步骤:
(1)安装mongodb(windows)
1)Mongodb官网下载文件
2)双击安装
点击 “Custom(自定义)” 按钮来设置你的安装目录,next,然后安装 “Install MongoDB Compass” 不够勾选
在这里插入图片描述在这里插入图片描述
3)配置
首先要在MongoDB的data文件夹里新建一个db文件夹和一个log文件夹
在这里插入图片描述
然后在log文件夹下新建一个mongo.log:
在这里插入图片描述
然后将E:\MongoDB\bin添加到环境变量path中,此时打开cmd窗口运行一下mongo命令,出现如下情况:
在这里插入图片描述
这是为什么呢?这是因为我们还没有启动MongoDB服务,自然也就连接不上服务了。那要怎么启动呢?在cmd窗口中运行如下命令:

mongod --dbpath E:\MongoDB\data\db

需要注意的是:如果你没有提前创建db文件夹,是无法启动成功的。运行成功之后,我们打开浏览器,输入127.0.0.1:27017,看到如下图,就说明MongoDB服务已经成功启动了。
在这里插入图片描述
注意:这个过程中如果报错,检查端口占用情况,看27017是否被占用,如果被占用,需要将其kill掉
参考链接
安装完成!

(2)Mongodb基本使用
参考链接
成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作。

输入help可以看到基本操作命令:
show dbs:显示数据库列表
show collections:显示当前数据库中的集合(类似关系数据库中的表)
use :切换当前数据库,这和MS-SQL里面的意思一样
db.foo.find():对于当前数据库中的foo集合进行数据查找(由于没有条件,会列出所有数据)
建数据库
参考链接
1)创建数据库

use test

创建用户

db.createUser(
  {
    user: "test",
    pwd: "test",
    roles: [ { role: "userAdmin", db: "test" } ]
  }
)

创建表

db.test.insert(
{
    "_id" : ObjectId("57172b0f657f8bbb34d70144"),
    "name" : "测试"
}
)

查看数据

db.test.find()

2)python 连接数据库mongodb
参考链接

import pymongo
import pandas as pd

MONGO_URI = 'mongodb://test:test@localhost:27017/test'
databasename = 'test'
tablename = 'test'
client = pymongo.MongoClient(MONGO_URI)
mongo_db = client[databasename]
mongo_db_collection = mongo_db[tablename]

# 存入数据库
try:
    if mongo_db_collection.insert(
    {
        "_id" : "345",
        "name" : "测试22"
    }
    ):
        print('存储到MongoDB成功')
except Exception:
    print('存储到MongoDb失败')
    
df = pd.DataFrame(list(mongo_db_collection.find({}, {'_id': 1, 'name': 1})))
print(df.head())

(3)爬取百科页面
参考链接
先创建两个表,分别是task和item
然后爬取
代码如下:

#! -*- coding:utf-8 -*-
#! -*- coding:utf-8 -*-

import requests as rq
import pandas as pd
import re
import time
import datetime
from multiprocessing.dummy import Pool
import pymongo #使用数据库负责存取
import urllib
from html.parser import HTMLParser
unescape = HTMLParser().unescape #用来实现对HTML字符的转移
MONGO_URI = 'mongodb://test:test@localhost:27017/test'
databasename = 'test'
tablename = 'test'
client = pymongo.MongoClient(MONGO_URI)

# mongo_db_collection.insert
headers = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
}

tasks = pymongo.MongoClient(MONGO_URI).test.task #将队列存于数据库中
items = pymongo.MongoClient(MONGO_URI).test.item #存放结果
tasks.create_index([('url', 'hashed')]) #建立索引,保证查询速度
items.create_index([('url', 'hashed')])

count = items.count() #已爬取页面总数
if tasks.count() == 0: #如果队列为空,就把该页面作为初始页面,这个页面要尽可能多超链接
    tasks.insert({'url':'https://baike.baidu.com/item/人乳头瘤病毒','url':'https://baike.baidu.com/item/HPV疫苗','url':'https://baike.baidu.com/item/HPV'})

url_split_re = re.compile('&|\+')
def clean_url(url):
    url = urllib.parse.urlparse(url)
    return url_split_re.split(urllib.parse.urlunparse((url.scheme, url.netloc, url.path, '', '', '')))[0]
def drop_urls(urls):
    '''
    删除不相关的url
    :return:
    '''
    urls = list(set(urls))
    tmp_urls = urls[:]
    drop_list = ['/item/秒懂本尊答','/item/秒懂大师说','/item/秒懂看瓦特','/item/秒懂五千年','/item/秒懂全视界','/item/百科热词团队','/item/%E7%96%A3/959775',
                 '/item/%E7%99%BE%E5%BA%A6%E7%99%BE%E7%A7%91%EF%BC%9A%E6%9C%AC%E4%BA%BA%E8%AF%8D%E6%9D%A1%E7%BC%96%E8%BE%91%E6%9C%8D%E5%8A%A1/22442459?bk_fr=pcFooter',
                 '/item/%E7%97%85%E6%AF%92']
    for url in urls:
        if url in drop_list:
            tmp_urls.remove(url)
    return tmp_urls
def main():
    global count
    while True:
        url = tasks.find_one_and_delete({})['url'] #取出一个url,并且在队列中删除掉
        print(url)
        sess = rq.get(url,headers=headers)
        web = sess.content.decode('utf-8')
        urls = re.findall(u'href="(/item/.*?)"', web) #查找所有站内链接
        #删除不相关的
        urls = drop_urls(urls)
        print(urls)
        for u in urls:
            try:
                u = urllib.unquote(str(u)).decode('utf-8')
            except:
                pass
            u = 'http://baike.baidu.com' + u
            u = clean_url(u)
            if not items.find_one({'url':u}): #把还没有队列过的链接加入队列
                tasks.update({'url':u}, {'$set':{'url':u}}, upsert=True)
        text = re.findall('<div class="content">([\s\S]*?)<div class="content">', web)
        basic_info = re.findall('<div class="basic-info cmn-clearfix">([\s\S]*?)</div>', web)
        basic_info_name = re.findall('<dt class="basicInfo-item name">([\s\S]*?)</dt>', basic_info[0])
        basic_info_vale = re.findall('<dd class="basicInfo-item value">([\s\S]*?)</dd>', basic_info[0])
        basic_info_name = '\t'.join([re.sub(u'[ \n\r\t\u3000]+', ' ', re.sub(u'<.*?>|\xa0', ' ', unescape(t))).strip() for t in basic_info_name])
        basic_info_vale = '\t'.join([re.sub(u'[ \n\r\t\u3000]+', ' ', re.sub(u'<.*?>|\xa0', ' ', unescape(t))).strip() for t in basic_info_vale])

        #爬取我们所需要的信息,需要正则表达式知识来根据网页源代码而写
        if text:
            text = ' '.join([re.sub(u'[ \n\r\t\u3000]+', ' ', re.sub(u'<.*?>|\xa0', ' ', unescape(t))).strip() for t in text]) #对爬取的结果做一些简单的处理
            title = re.findall(u'<title>(.*?)_百度百科</title>', web)[0]
            # left_dls = soup.body.find("dl", class_="basicInfo-block basicInfo-left")
            # triple =
            items.update({'url':url}, {'$set':{'url':url, 'title':title, 'text':text,'basic_info_name':basic_info_name,'basic_info_vale':basic_info_vale}}, upsert=True)
            count += 1
            print (u'%s, 爬取《%s》,URL: %s, 已经爬取%s'%(datetime.datetime.now(), title, url, count))

        pool = Pool(4, main) #多线程爬取,4是线程数
        time.sleep(60)
        while tasks.count() > 0:
            time.sleep(60)

        pool.terminate()

if __name__ == "__main__":
    # main()

    df = pd.DataFrame(list(client.test.item.find({}, {'url': 1, 'title': 1, 'basic_info_name': 1, 'basic_info_vale': 1, 'text': 1})))
    # df.to_csv(r"F:\relation_extraction\data\get_all_from_baike.csv",index=False)
    triples = []
    for index,row in df.iterrows():
        title = row['title']
        basic_info_name = row['basic_info_name'].split('\t')
        basic_info_vale = row['basic_info_vale'].split('\t')
        n = len(basic_info_name)
        for i in range(n):
            with open(r"F:\relation_extraction\data\get_triple_from_baike.csv",'a',encoding='utf8') as f:
                f.write('\t'.join([title,basic_info_name[i],basic_info_vale[i]])+'\n')
    print(df.head())

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值