13-数据采集项目03

一、Hive上的数据导入

##4. 创建ods层
[root@hadoop hive-1.2.1]# beeline -u jdbc:hive2://caiji:10000 -n root -p 123456 -e "create database if not exists ods_news"
[root@hadoop hive-1.2.1]# beeline -u jdbc:hive2://caiji:10000 -n root -p 123456 -e "show databases"

也可以使用hive中的命令,hive -e "sql语句"

接着上传两个jar包:

这两个jar包使用来处理json数据的。因为我们上传到hdfs上的数据是json格式的。

创建文件夹:hdfs dfs -mkdir -p /common/lib
将两个文件上传至hdfs的这个/common/lib目录下面
hdfs dfs -put json-serde-1.3.8-jar-with-dependencies.jar /common/lib
hdfs dfs -put json-udf-1.3.8-jar-with-dependencies.jar /common/lib
[root@hadoop ~]# vi ~/.hiverc
add jar hdfs:///common/lib/json-udf-1.3.8-jar-with-dependencies.jar;
add jar hdfs:///common/lib/json-serde-1.3.8-jar-with-dependencies.jar;

##7.beeline需要手动指定这个文件的位置
beeline -i ~/.hiverc

.hiverc 文件到底放在哪里?
假如你经常使用hive,就把这个文件放在hive/conf 下,每次hive 进入的时候就会加载这个文件。

创建表的语句,解析: 

{
    "ctime": 1589781236541,
    "project": "news",
    "content": {
    "distinct_id": "51818968",
    "event": "AppClick",
    "properties": {
    "element_page": "新闻列表页",
    "screen_width": "640",
    "app_version": "1.0",
    "os": "GNU/Linux",
    "battery_level": "11",
    "device_id": "886113235750",
    "client_time": "2020-05-18 13:53:56",
    "ip": "61.233.88.41",
    "is_charging": "1",
    "manufacturer": "Apple",
    "carrier": "中国电信",
    "screen_height": "320",
    "imei": "886113235750",
    "model": "",
    "network_type": "WIFI",
    "element_name": "tag"
  }
  }
  }
CREATE EXTERNAL TABLE if not exists ods_news.news
 (
   project string,
   ctime string,
   content struct<
      distinct_id:string,
      event:string,
      properties:
          struct<model:string,
                network_type:string,
                is_charging:string,
                app_version:string,
                element_name:string,
                 element_page:string,
                 carrier:string,
                 os:string,
                 imei:string,
                 battery_level:string,
                 screen_width:string,
                 screen_height:string,
                 device_id:string,
                 client_time:string,
                 ip:string,
                 manufacturer:string>>) 
   PARTITIONED BY(logday string) 
   ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' 
LOCATION '/sources/news/'

两种办法:第一种,进入hive ,执行建表语句
第二种:beeline -i ~/.hiverc  -u jdbc:hive2://caiji:10000 -n root -p 123456 -e "CREATE EXTERNAL TABLE if not exists ods_news.news
 (
   project string,
   ctime string,
   content struct<
      distinct_id:string,
      event:string,
      properties:
          struct<model:string,
                network_type:string,
                is_charging:string,
                app_version:string,
                element_name:string,
                 element_page:string,
                 carrier:string,
                 os:string,
                 imei:string,
                 battery_level:string,
                 screen_width:string,
                 screen_height:string,
                 device_id:string,
                 client_time:string,
                 ip:string,
                 manufacturer:string>>) 
   PARTITIONED BY(logday string) 
   ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' 
LOCATION '/sources/news/'"
由于 数据中有json,想要将json解析为 数据,需要指定解析的规则 org.openx.data.jsonserde.JsonSerDe
你想使用这个类,就必须导入包。

使用一个脚本,创建news表,并且添加分区

alter table ods_news.news add partition(logday='20230913') location '/sources/news/20230913';

复习一下如何获取一个日期的前一天
[root@caiji ~]# date -d "2023-09-14 1 days ago" +%Y%m%d
20230913
[root@caiji ~]# date -d "1 days ago" +%Y%m%d
20230912

news_add_partition.sh

#!/bin/bash
# filename:news_add_partition.sh
# author:laoyan
# date:2022-06-15
# desc:将hdfs的行为数据和hive做映射

##1. 申明变量
B_HOST=caiji
B_PORT=10000
B_USER=root
HIVE_HOME=/opt/installs/hive

##2. 导入的日期
exec_date=$1

if [ "${exec_date}" ]; then
	exec_date=`date -d "${exec_date} 1 days ago" +%Y%m%d`
else
	exec_date=`date -d "1 days ago" +%Y%m%d`
fi

echo "news_add_partition.sh exec_date is ${exec_date}"

##3. 建表的SQL
CREATE_TABLE_SQL="CREATE EXTERNAL TABLE if not exists ods_news.news(project string,ctime string,content struct<distinct_id:string,event:string,properties:struct<model:string,network_type:string,is_charging:string,app_version:string,element_name:string,element_page:string,carrier:string,os:string,imei:string,battery_level:string,screen_width:string,screen_height:string,device_id:string,client_time:string,ip:string,manufacturer:string>>) PARTITIONED BY(logday string) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' LOCATION '/sources/news/'"

echo "${CREATE_TABLE_SQL}"

${HIVE_HOME}/bin/beeline -i ~/.hiverc -n ${B_USER} -p 123456 -u jdbc:hive2://${B_HOST}:${B_PORT} -e "${CREATE_TABLE_SQL}"

##4. 修改表:添加分区
ADD_PARTITION_SQL="alter table ods_news.news drop if exists partition(logday='${exec_date}');alter table ods_news.news add partition(logday='${exec_date}') location 'hdfs://${B_HOST}:9820/sources/news/${exec_date}';"

echo "${ADD_PARTITION_SQL}"

${HIVE_HOME}/bin/beeline -i ~/.hiverc -n ${B_USER} -p 123456 -u jdbc:hive2://${B_HOST}:${B_PORT} -e "${ADD_PARTITION_SQL}"

##5. 结束
echo "insert successful"

以上脚本只干了两件事情:

1、创建分区表

2、创建分区表中的一个分区

查看分区信息:

 show partitions news;

映射到有数据的分区文件夹下,比如,我有20221008有数据

sh news_add_partition.sh 20230914
0: jdbc:hive2://spark01:10000> select * from news limit 10;
Error: java.lang.Error: Data is not JSONObject  but java.lang.String with value {"distinct_id":"0","type":"profile_set","uuid":"b5fb482e-e2e6-470e-8f35-6cf0524f49a3","properties":{"gender":"男","nick_name":"Delilah BrekkePadberg.2556","mobile":"+8616658378336","name":"薄婉静","signup_time":1665215649000,"email":"Devonte.Bruen2777@yahoo.com","age":"82"}} (state=,code=0)

删除掉之前的数据:
hdfs dfs -rm -R /sources/news/20230913/*
重新采集一下。

[root@caiji scripts]# pgrep -af nginx
107947 nginx: master process openresty -p /opt/apps/collect-app/
107948 nginx: worker process              
107949 nginx: worker process              
107950 nginx: worker process              
107951 nginx: worker process

启动frpc服务:
frpc http --sd yanlaoshi -l 8802 -s frp.qfbigdata.com:7001 -u yanlaoshi

同步一下时间:
ntpdate time1.aliyun.com

启动flume脚本,抽取数据
./flume-agent.sh

定时任务需要启动  systemctl status crond

进入hive ,查看数据:

hive 在进入数据库的时候,会加载 conf / .hiverc 文件,你没有,加载不了jar包,所以报错,怎么解决,在conf下创建一个hiverc
cp ~/.hiverc /opt/installs/hive/conf/
或者直接使用beeline ,    beeline -i  ~/.hiverc

 

当你的分区下有tmp文件的时候,就会查询到null,这个是一个正常的现象。

假如你执行sql语句:select count(1) from news; 报错

yarn-site.xml中

<property>
  <name>yarn.application.classpath</name>
  <value>你的路径信息(刚才复制的路径信息)</value>
</property>

value值,通过 hadoop classpath命令获取到

<property>
  <name>yarn.application.classpath</name>
  <value>/opt/installs/hadoop/etc/hadoop:/opt/installs/hadoop/share/hadoop/common/lib/*:/opt/installs/hadoop/share/hadoop/common/*:/opt/installs/hadoop/share/hadoop/hdfs:/opt/installs/hadoop/share/hadoop/hdfs/lib/*:/opt/installs/hadoop/share/hadoop/hdfs/*:/opt/installs/hadoop/share/hadoop/mapreduce/*:/opt/installs/hadoop/share/hadoop/yarn:/opt/installs/hadoop/share/hadoop/yarn/lib/*:/opt/installs/hadoop/share/hadoop/yarn/*</value>
</property>


重启yarn服务,即可。

假如你flume抽取数据的时候,抽取不成功,什么错误都不报。

flume的执行 flume 的job 下面。
flume-ng agent -n a1 -c ../conf/ -f collect-app-agent.conf

在别的目录下,执行的是绝对路径:
flume-ng agent -n a1 -c /opt/installs/flume/conf/ -f /opt/installs/flume/job/collect-app-agent.conf

尝试使用相对路径,不要使用绝对路径
还有一个错误:
你的文件夹下 20230913日的数据
但是你创建了一个20230914号的分区
分区是不是每天都要创建一个?是,谁创建,自动创建(使用脚本+定时任务)

二、业务数据【数据库】采集

1、业务数据来自于数据

创建数据库biz,然后导入数据 biz.sql

2、sqoop连接数据库

sqoop list-databases \
--connect jdbc:mysql://caiji:3306?useSSL=false \
--username root \
--password 123456

 3、通过sqoop 将mysql的数据采集到hdfs上

sqoop import --connect jdbc:mysql://192.168.235.140:3306/sqoop \
--username root --password 123456 \
--query 'select empno,sal,mgr,job from emp where empno<7788 and $CONDITIONS' \
--target-dir /home \
--delete-target-dir \
--split-by empno \
-m 1

4、编写一个脚本可以抽取数据到hdfs上

如果指定了时间,就抽取这个时间的前一天,如果没有指定时间,当前时间的前一天

biz2hdfs.sh

#!/bin/bash
# filename:biz2hdfs.sh
# author:laoyan
# date:2022-06-15
# desc:sqoop导入biz的数据到hdfs

## 变量
SQOOP_HOME=/opt/installs/sqoop
MYSQL_URI=jdbc:mysql://caiji:3306/biz?useSSL=false
MYSQL_USR=root
MYSQL_PWD=123456

## 定义一个日期,如果你输入了日期,就采集这个日期的前一天的数据。如果没有输入日期,我们就采集昨天的数据
exec_date=$1

if [ "${exec_date}" ]; then
exec_date=`date -d "${exec_date} 1 days ago" +%Y%m%d`
else
exec_date=`date -d "1 days ago" +%Y%m%d`
fi

echo "biz2hdfs.sh exec_date is ${exec_date}"

## 将exec_date转换为sql_date: %Y%m%d -> %Y-%m-%d
SQL_DATE=`date -d "${exec_date}" +%Y-%m-%d`
echo "SQL_Date is ${SQL_DATE}"

## 导入数据
## ad_info
${SQOOP_HOME}/bin/sqoop import \
--connect ${MYSQL_URI} \
--username ${MYSQL_USR} \
--password ${MYSQL_PWD} \
--query "select id, cast(ad_id as char(50)) as ad_id, cast(advertiser_id as char(50)) as advertiser_id, advertiser_name, date_format(create_time, '%Y-%m-%d %H:%i:%s') as create_time, date_format(update_time, '%Y-%m-%d %H:%i:%s') as update_time from ad_info where 1=1 and create_time<='${SQL_DATE} 00:00:00' and \$CONDITIONS" \
--as-parquetfile \
--target-dir /sources/news-biz/ad_info/${exec_date} \
--delete-target-dir \
--split-by id \
--num-mappers 3

## meta
${SQOOP_HOME}/bin/sqoop import \
--connect ${MYSQL_URI} \
--username ${MYSQL_USR} \
--password ${MYSQL_PWD} \
--query "select id, field, field_type, field_desc, app_version, cast(status as char(50)) as status, date_format(create_time, '%Y-%m-%d %H:%i:%s') as create_time, date_format(update_time, '%Y-%m-%d %H:%i:%s') as update_time from meta where 1=1 and create_time<'${SQL_DATE} 00:00:00' and \$CONDITIONS" \
--as-parquetfile \
--target-dir /sources/news-biz/meta/${exec_date} \
--delete-target-dir \
--split-by id \
--num-mappers 3

运行过程出现这个错误:

在yarn-site.xml中,添加如下配置:


<property>
  <name>yarn.application.classpath</name>
  <value>你的路径信息(刚才复制的路径信息)</value>
</property>

value值,通过 hadoop classpath命令获取到

如果之前采集过,直接删除hdfs上的数据

hdfs dfs -rm -r /sources/news-biz

执行脚本进行采集

sh biz2hdfs.sh
为什么有时候  ./biz2hdfs.sh    有时候 sh biz2hdfs.sh 
如果./ 当前文件夹的意思,这个sh文件必须是可执行文件,是需要赋权限的  chmod u+x biz2hdfs.sh 
sh biz2hdfs.sh 它的意思是通过sh 解释器解释执行这个文件,不需要添加权限 

5、将hdfs上的数据映射到hive表中

编写 biz_add_partition.sh

使用hive创建了两个表,并且增加了分区

#!/bin/bash
# filename:biz_add_partition.sh
# author:laoyan
# date:2022-06-16
# desc:将hdfs的业务数据和hive做映射

##1. 申明变量
B_HOST=caiji
B_PORT=10000
B_USER=root
HIVE_HOME=/opt/installs/hive

##2. 导入的日期
exec_date=$1

if [ "${exec_date}" ]; then
	exec_date=`date -d "${exec_date} 1 days ago" +%Y%m%d`
else
	exec_date=`date -d "1 days ago" +%Y%m%d`
fi

echo "biz_add_partition.sh exec_date is ${exec_date}"

##3. 建表的SQL
##3.1 meta
CREATE_META_TABLE_SQL="CREATE external TABLE ods_news.meta (
  field string,
  field_type string,
  field_desc string,
  app_version string,
  status string,
  create_time string,
  update_time string
)
partitioned by(logday string)
stored as parquet
location '/sources/news-biz/meta'"

echo "${CREATE_META_TABLE_SQL}"

${HIVE_HOME}/bin/beeline -i ~/.hiverc -n ${B_USER} -p 123456 -u jdbc:hive2://${B_HOST}:${B_PORT} -e "${CREATE_META_TABLE_SQL}"

##3.2 ad
CREATE_AD_TABLE_SQL="CREATE external TABLE ods_news.ad_info (
  ad_id string,
  advertiser_id string,
  advertiser_name string,
  create_time string,
  update_time string
) 
partitioned by(logday string)
stored as parquet
location '/sources/news-biz/ad_info'"

echo "${CREATE_AD_TABLE_SQL}"

${HIVE_HOME}/bin/beeline -i ~/.hiverc -n ${B_USER} -p 123456 -u jdbc:hive2://${B_HOST}:${B_PORT} -e "${CREATE_AD_TABLE_SQL}"


##4. 修改表:添加分区
ADD_PARTITION_SQL="alter table ods_news.meta drop if exists partition(logday='${exec_date}');alter table ods_news.ad_info drop if exists partition(logday='${exec_date}');alter table ods_news.meta add partition(logday='${exec_date}') location '/sources/news-biz/meta/${exec_date}';alter table ods_news.ad_info add partition(logday='${exec_date}') location '/sources/news-biz/ad_info/${exec_date}';"

echo "${ADD_PARTITION_SQL}"

${HIVE_HOME}/bin/beeline -i ~/.hiverc -n ${B_USER} -p 123456 -u jdbc:hive2://${B_HOST}:${B_PORT} -e "${ADD_PARTITION_SQL}"

##5. 结束
echo "insert successful"

<think>嗯,用户想通过GitHub爬取2023到2025年间发布的150个中国开源GenAI项目的交互日志数据。首先,我需要确定什么是交互日志数据,可能包括提交记录、问题讨论、PR记录等。然后,如何找到这些中国项目呢?可能需要用GitHub的搜索API,加上语言或地区的过滤?不过GitHub的地区标签可能不太明确,可能需要用中文描述或项目名称中的关键词来筛选。 接下来是工具选择。Python的requests库或者Scrapy框架可能适合。GitHub API有速率限制,需要处理分页和认证。用户可能需要注册GitHub开发者应用,获取token来提升请求限额。另外,存储数据的话,可能需要用数据库,比如MySQL或者MongoDB,或者直接保存为JSON文件。 步骤方面,首先是确定项目筛选条件,比如时间范围、主题标签(GenAI)、地区。不过GitHub没有直接的地区分类,可能需要通过仓库描述中的关键词来判断,比如“中国”、“China”或者项目维护者的地理位置信息。但这个方法可能不太准确,需要进一步考虑。 然后,使用GitHub的搜索API,比如搜索仓库创建时间在2023-01-01到2025-12-31之间,主题包含生成式AI相关的关键词,比如“generative AI”、“GenAI”等,并且可能用中文关键词。接着,遍历搜索结果,收集仓库的URL和基本信息。 获取到仓库列表后,需要抓取每个仓库的交互日志。这包括Issues、PRs、Commits、Stars、Forks等数据。每个部分都有对应的API端点,比如/issues,/pulls,/commits。要注意分页参数,确保获取所有记录。 处理速率限制是关键,GitHub API的认证用户每小时有5000次请求,未认证的只有60次。所以用户必须使用个人访问令牌。此外,可能需要使用时间延迟或并发请求来优化效率,但要注意不要触发限制。 数据存储部分,可能需要结构化存储,比如按项目分表,记录每个交互事件的时间、用户、内容等。或者使用NoSQL数据库,更灵活。数据清洗也是必要的,比如去重、格式化时间戳、处理特殊字符等。 还有法律和道德问题,必须遵守GitHub的服务条款,robots.txt,以及尊重项目的许可证。不能爬取私有仓库的数据,且要避免对GitHub服务器造成过大负担。 可能遇到的问题:如何准确筛选中国项目?可能需要结合仓库描述、维护者的资料、README中的中文内容等。另外,时间范围到2025年,目前还没到,可能需要定期更新爬虫,或者设置自动化的持续收集。 工具方面,除了Python,还有现成的工具如Octokit(GitHub官方库),或者第三方库PyGithub,可以简化API调用。数据可视化或分析可能需要用到Pandas或ELK栈。 最后,生成相关问题需要考虑用户可能关心的扩展内容,比如数据处理方法、法律风险、数据分析工具等。</think>### 分步指南:通过GitHub爬取中国开源GenAI项目交互日志数据 #### 一、明确数据范围与定义 1. **交互日志数据类型**:包括仓库的提交记录(Commits)、问题讨论(Issues)、拉取请求(Pull Requests)、Star/Fork事件、版本发布(Releases)等[^4]。 2. **筛选条件**: - 时间范围:2023年1月1日至2025年12月31日 - 项目标签:包含`GenAI`、`生成式AI`、`LLM`等关键词 - 地区标识:仓库描述含`中国`/`China`,或维护者资料含中文信息 #### 二、工具准备 | 工具类型 | 推荐工具 | |----------------|--------------------------------------------------------------------------| | API调用库 | Python的`PyGithub`库、`requests`库 | | 数据存储 | MySQL/MongoDB(结构化存储)或JSON/CSV(轻量级) | | 反爬虫处理 | 代理池(如Scrapy-ProxyPool)、请求延迟设置 | | 数据分析 | Pandas(数据清洗)、ELK栈(日志分析) | #### 三、核心步骤 1. **获取项目清单** - 使用GitHub搜索API构造查询: ```python from github import Github g = Github("your_token") query = 'GenAI created:2023-01-01..2025-12-31 language:zh OR description:中国' repos = g.search_repositories(query) ``` - 提取仓库全名(如`krahets/hello-algo`)和API地址[^1] 2. **爬取交互日志** 对每个仓库调用以下API端点: ```python # 示例:获取Issues repo = g.get_repo("owner/repo_name") issues = repo.get_issues(state="all") # 含已关闭的Issue for issue in issues: print(issue.title, issue.user.login, issue.created_at) ``` 3. **处理分页与限流** - GitHub API默认每页30条,需循环遍历`page`参数 - 使用`time.sleep(1)`避免触发速率限制(认证后上限5000次/小时) 4. **数据清洗与存储** - 结构化字段示例: ```json { "event_type": "issue", "repo": "git-ecosystem/git-credential-manager", "author": "dev-user", "timestamp": "2024-03-15T08:00:00Z", "content": "发现认证流程的兼容性问题..." } ``` - 去重策略:通过`event_id`(如Commit SHA/Issue ID)建立唯一索引 #### 四、完整代码框架 ```python import csv from github import Github # 初始化 g = Github("ghp_YourToken123") writer = csv.writer(open('genai_logs.csv', 'w')) # 爬取过程 for repo in g.search_repositories('GenAI created:>=2023-01-01'): # 获取Issues for issue in repo.get_issues(): writer.writerow([ repo.full_name, 'issue', issue.id, issue.user.login, issue.created_at, issue.title ]) # 获取Commits(需处理分页) for commit in repo.get_commits(): writer.writerow([ repo.full_name, 'commit', commit.sha, commit.author.login, commit.commit.author.date, commit.commit.message ]) ``` #### 五、注意事项 1. **法律合规** - 遵守[GitHub服务条款](https://docs.github.com/terms)第E.13条:禁止影响服务性能的自动化请求 - 敏感数据需匿名化处理(如用户邮箱替换为哈希值) 2. **道德约束** - 仅爬取公开仓库数据 - 在仓库的`LICENSE`允许范围内使用数据 #### 六、扩展工具推荐 - **Git-Repo-Monitor**:监控仓库更新的开源工具(含Commit/PR订阅功能)[^2] - **GHArchive**:预处理的GitHub事件数据集(需二次筛选)[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YuPangZa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值