baidu 1.2.10 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +82 -0
- data/Rakefile +1 -0
- data/baidu.gemspec +26 -0
- data/lib/baidu.rb +46 -468
- data/lib/baidu/auth.rb +5 -0
- data/lib/baidu/map.rb +66 -0
- data/lib/baidu/rank.rb +5 -0
- data/lib/baidu/sem.rb +14 -0
- data/lib/baidu/sem/account.rb +31 -0
- data/lib/baidu/sem/adgroup.rb +55 -0
- data/lib/baidu/sem/base.rb +96 -0
- data/lib/baidu/sem/bulk.rb +75 -0
- data/lib/baidu/sem/campaign.rb +96 -0
- data/lib/baidu/sem/creative.rb +33 -0
- data/lib/baidu/sem/enum.rb +70 -0
- data/lib/baidu/sem/keyword.rb +35 -0
- data/lib/baidu/sem/kr.rb +9 -0
- data/lib/baidu/sem/new_creative.rb +32 -0
- data/lib/baidu/sem/report.rb +107 -0
- data/lib/baidu/sem/search.rb +79 -0
- data/lib/baidu/version.rb +3 -0
- data/lib/ext.rb +46 -0
- data/spec/map_spec.rb +77 -0
- data/spec/sem_adgroup_spec.rb +119 -0
- data/spec/sem_api_response_spec.rb +97 -0
- data/spec/sem_bulk_spec.rb +89 -0
- data/spec/sem_campaign_spec.rb +94 -0
- data/spec/sem_creative_spec.rb +79 -0
- data/spec/sem_keyword_spec.rb +48 -0
- data/spec/sem_report_spec.rb +52 -0
- data/spec/sem_search_spec.rb +80 -0
- data/spec/spec_helper.rb +356 -0
- metadata +87 -15
@@ -0,0 +1,33 @@
|
|
1
|
+
module Baidu
|
2
|
+
module SEM
|
3
|
+
class CreativeService < Base
|
4
|
+
# def getCreativeIdByAdgroupId
|
5
|
+
|
6
|
+
# end
|
7
|
+
# def getCreativeByAdgroupId
|
8
|
+
|
9
|
+
# end
|
10
|
+
# def getCreativeByCreativeId
|
11
|
+
|
12
|
+
# end
|
13
|
+
# def addCreative
|
14
|
+
|
15
|
+
# end
|
16
|
+
# def updateCreative
|
17
|
+
|
18
|
+
# end
|
19
|
+
# def deleteCreative
|
20
|
+
|
21
|
+
# end
|
22
|
+
# def activateCreative
|
23
|
+
|
24
|
+
# end
|
25
|
+
# def getCreativeStatus
|
26
|
+
|
27
|
+
# end
|
28
|
+
# def getCreativeStatusZip
|
29
|
+
|
30
|
+
# end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Baidu
|
2
|
+
module SEM
|
3
|
+
module Format
|
4
|
+
CSV = 2
|
5
|
+
end
|
6
|
+
|
7
|
+
module ReportState
|
8
|
+
PENDING = 1 #等待中
|
9
|
+
DOING = 2 #处理中
|
10
|
+
DONE = 3 #处理成功
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
module PerformanceData
|
15
|
+
COST = 'cost' #消费
|
16
|
+
CPC = 'cpc' #每个点击的消费
|
17
|
+
CLICK = 'click' #点击数
|
18
|
+
IMPRESSION = 'impression' #展示量
|
19
|
+
CTR = 'ctr' #转化率
|
20
|
+
CPM = 'cpm' #?
|
21
|
+
POSITION = 'position' #?
|
22
|
+
CONVERSION = 'conversion' #?
|
23
|
+
end
|
24
|
+
|
25
|
+
module LevelOfDetails
|
26
|
+
PORTFOLIO = 2 #账户粒度
|
27
|
+
CAMPAIGN = 3 #计划粒度
|
28
|
+
ADGROUP = 5 #单元粒度
|
29
|
+
CREATIVE = 7 #创意粒度
|
30
|
+
KEYWORDID = 11 #关键词(keywordid)粒度
|
31
|
+
KEYWORD = 12 #关键词(keywordid)+创意粒度
|
32
|
+
end
|
33
|
+
|
34
|
+
module ReportType
|
35
|
+
PORTFOLIO = 2 #账户
|
36
|
+
CAMPAIGN = 10 #计划
|
37
|
+
ADGROUP = 11 #单元
|
38
|
+
KEYWORDID = 14 #关键词(keywordid)
|
39
|
+
CREATIVE = 12 #创意
|
40
|
+
PAIR = 15 #配对
|
41
|
+
REGION = 3 #地域
|
42
|
+
QUERY = 6 #搜索词
|
43
|
+
WORD = 9 #关键词(wordid)
|
44
|
+
end
|
45
|
+
|
46
|
+
module StatRange #注意:统计范围不能细于当前的统计 粒度,例如统计粒度为计划,则统计 范围不能细到单元
|
47
|
+
PORTFOLIO = 2 #账户范围
|
48
|
+
CAMPAIGN = 3 #计划范围
|
49
|
+
ADGROUP = 5 #单元范围
|
50
|
+
CREATIVE = 7 #创意范围
|
51
|
+
KEYWORDID = 11 #关键词(keywordid)范围
|
52
|
+
WORD = 6 #关键词(wordid)范围
|
53
|
+
end
|
54
|
+
|
55
|
+
module UnitOfTime
|
56
|
+
DAY = 5 #分日
|
57
|
+
WEEK = 4 #分周
|
58
|
+
MONTH = 3 #分月
|
59
|
+
YEAR = 1 #分年
|
60
|
+
HOUR = 7 #分小时
|
61
|
+
TIME = 8 #请求时间段汇总(endDate-StartDate)
|
62
|
+
end
|
63
|
+
|
64
|
+
module Device
|
65
|
+
ALL = 0 #全部搜索推广设备
|
66
|
+
PC = 1 #仅计算机
|
67
|
+
MOBILE = 2 #仅移动 
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Baidu
|
2
|
+
module SEM
|
3
|
+
class KeywordService < Base
|
4
|
+
# def getKeywordIdByAdgroupId
|
5
|
+
# end
|
6
|
+
# def getKeywordByAdgroupId
|
7
|
+
# end
|
8
|
+
# def getKeywordByKeywordId
|
9
|
+
# end
|
10
|
+
# def addKeyword
|
11
|
+
# end
|
12
|
+
# def updateKeyword
|
13
|
+
|
14
|
+
# end
|
15
|
+
# def deleteKeyword
|
16
|
+
|
17
|
+
# end
|
18
|
+
# def activateKeyword
|
19
|
+
|
20
|
+
# end
|
21
|
+
# def getKeywordStatus
|
22
|
+
|
23
|
+
# end
|
24
|
+
# def getKeywordStatusZip
|
25
|
+
|
26
|
+
# end
|
27
|
+
# def getKeywordQuality
|
28
|
+
|
29
|
+
# end
|
30
|
+
# def getKeywordQualityZip
|
31
|
+
|
32
|
+
# end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/baidu/sem/kr.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Baidu
|
2
|
+
module SEM
|
3
|
+
class NewCreativeService < Base
|
4
|
+
# def getSublinkIdByAdgroupId
|
5
|
+
|
6
|
+
# end
|
7
|
+
# def getSublinkBySublinkId
|
8
|
+
|
9
|
+
# end
|
10
|
+
# def addSublink
|
11
|
+
|
12
|
+
# end
|
13
|
+
# def updateSublink
|
14
|
+
|
15
|
+
# end
|
16
|
+
# def deleteSublink
|
17
|
+
|
18
|
+
# end
|
19
|
+
# def addMobileSublink
|
20
|
+
|
21
|
+
# end
|
22
|
+
# def updateMobileSublink
|
23
|
+
# end
|
24
|
+
# def getMobileSublinkIdByAdgroupId
|
25
|
+
|
26
|
+
# end
|
27
|
+
# def getMobileSublinkBySublinkId
|
28
|
+
|
29
|
+
# end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Baidu
|
2
|
+
module SEM
|
3
|
+
class ReportService < Base
|
4
|
+
# def getProfessionalReportId(options)
|
5
|
+
# necessary_options = [:performanceData, :startDate, :endDate, :statIds]
|
6
|
+
# raise "necessary options:#{necessary_options}" if invalid_options?(options,necessary_options)
|
7
|
+
# operation = make_operation('getProfessionalReportId')
|
8
|
+
# operation.header = operation_header
|
9
|
+
# operation.body = {
|
10
|
+
# :getProfessionalReportIdRequest=>{
|
11
|
+
# :reportRequestType => options
|
12
|
+
# }
|
13
|
+
# }
|
14
|
+
# if @debug
|
15
|
+
# puts operation.build
|
16
|
+
# end
|
17
|
+
# response = operation.call
|
18
|
+
# if @debug
|
19
|
+
# p response.hash
|
20
|
+
# end
|
21
|
+
# response = response.body[:get_professional_report_id_response]
|
22
|
+
# return false if response.nil? or response[:report_id].nil?
|
23
|
+
# response[:report_id].to_s
|
24
|
+
# end
|
25
|
+
|
26
|
+
# def getRealTimeData
|
27
|
+
# operation = make_operation('getRealTimeData')
|
28
|
+
# end
|
29
|
+
|
30
|
+
# def getReportState(report_id)
|
31
|
+
# raise "your input report_id:#{report_id} is invalid" unless report_id =~ /[a-z0-9]{32}/
|
32
|
+
# operation = make_operation('getReportState')
|
33
|
+
# operation.header = operation_header
|
34
|
+
# operation.body = {
|
35
|
+
# :getReportStateRequest => {
|
36
|
+
# :reportId => report_id
|
37
|
+
# }
|
38
|
+
# }
|
39
|
+
# if @debug
|
40
|
+
# puts operation.build
|
41
|
+
# end
|
42
|
+
# response = operation.call
|
43
|
+
# if @debug
|
44
|
+
# p response.hash
|
45
|
+
# end
|
46
|
+
# response = response.body
|
47
|
+
# return false if response.nil? or response[:get_report_state_response].nil? or response[:get_report_state_response][:is_generated].nil?
|
48
|
+
# response[:get_report_state_response][:is_generated]
|
49
|
+
# end
|
50
|
+
|
51
|
+
# def getReportFileUrl(report_id)
|
52
|
+
# raise "report_id invalid" unless report_id =~ /[a-z0-9]{32}/
|
53
|
+
# operation = make_operation('getReportFileUrl')
|
54
|
+
# operation.header = operation_header
|
55
|
+
# operation.body = {
|
56
|
+
# :getReportFileUrlRequest=>{
|
57
|
+
# :reportId=>report_id
|
58
|
+
# }
|
59
|
+
# }
|
60
|
+
|
61
|
+
# if @debug
|
62
|
+
# puts operation.build
|
63
|
+
# end
|
64
|
+
|
65
|
+
# response = operation.call
|
66
|
+
|
67
|
+
# if @debug
|
68
|
+
# p response.hash
|
69
|
+
# end
|
70
|
+
|
71
|
+
# response = response.body[:get_report_file_url_response]
|
72
|
+
# return false if response.nil? or response[:report_file_path].nil?
|
73
|
+
# response[:report_file_path]
|
74
|
+
# end
|
75
|
+
# def getRealTimeQueryData(options)
|
76
|
+
# abort 'not ready'
|
77
|
+
# necessary_options = [:performanceData, :startDate, :endDate, :statIds]
|
78
|
+
# raise "necessary options:#{necessary_options}" if invalid_options?(options,necessary_options)
|
79
|
+
# operation = make_operation('getRealTimeQueryData')
|
80
|
+
# operation.header = operation_header
|
81
|
+
# operation.body = {
|
82
|
+
# :getRealTimeQueryDataRequest=>{
|
83
|
+
# :realTimeQueryRequestTypes => options
|
84
|
+
# }
|
85
|
+
# }
|
86
|
+
# if @debug
|
87
|
+
# puts operation.build
|
88
|
+
# end
|
89
|
+
# response = operation.call
|
90
|
+
# if @debug
|
91
|
+
# p response.hash
|
92
|
+
# end
|
93
|
+
# # response.body[:get_professional_report_id_response]
|
94
|
+
|
95
|
+
# end
|
96
|
+
# def getRealTimePairData(options)
|
97
|
+
# operation = make_operation("getRealTimePairData")
|
98
|
+
# operation.header = operation_header
|
99
|
+
# operation.body = {
|
100
|
+
# :getRealTimePairDataRequest =>{
|
101
|
+
# :realTimePairRequestTypes =>options
|
102
|
+
# }
|
103
|
+
# }
|
104
|
+
# end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Baidu
|
2
|
+
module SEM
|
3
|
+
class SearchService < Base
|
4
|
+
# class SearchResponse
|
5
|
+
# attr_accessor :more,:results
|
6
|
+
# end
|
7
|
+
|
8
|
+
# def getKeywordBySearch(options)
|
9
|
+
# operation = make_operation('getKeywordBySearch')
|
10
|
+
# operation.header = operation_header
|
11
|
+
# operation.body = {
|
12
|
+
# :getKeywordBySearchRequest=> options
|
13
|
+
# }
|
14
|
+
# response = operation.call
|
15
|
+
# puts operation.build if @debug
|
16
|
+
# ap response if @debug
|
17
|
+
# response = response.body[:get_keyword_by_search_response]
|
18
|
+
# r = SearchResponse.new
|
19
|
+
# r.results = response[:keyword_infos]
|
20
|
+
# r.more = response[:more_word].to_i
|
21
|
+
# r
|
22
|
+
# end
|
23
|
+
|
24
|
+
|
25
|
+
# def getAdgroupBySearch(options)
|
26
|
+
# operation = make_operation('getAdgroupBySearch')
|
27
|
+
# operation.header = operation_header
|
28
|
+
# operation.body = {
|
29
|
+
# :getAdgroupBySearchRequest=>options
|
30
|
+
# }
|
31
|
+
# response = operation.call
|
32
|
+
|
33
|
+
# if @debug
|
34
|
+
# puts operation.build
|
35
|
+
# end
|
36
|
+
# response = response.body[:get_adgroup_by_search_response]
|
37
|
+
# r = SearchResponse.new
|
38
|
+
# r.more = response[:more_adgroup].to_i
|
39
|
+
# r.results = response[:adgroup_infos]
|
40
|
+
# r
|
41
|
+
# end
|
42
|
+
|
43
|
+
# def getCampaignBySearch(options)
|
44
|
+
# operation = make_operation('getCampaignBySearch')
|
45
|
+
# operation.header = operation_header
|
46
|
+
# operation.body = {
|
47
|
+
# :getCampaignBySearchRequest=>options
|
48
|
+
# }
|
49
|
+
# response = operation.call
|
50
|
+
# if @debug
|
51
|
+
# puts operation.build
|
52
|
+
# end
|
53
|
+
# response = response.body[:get_campaign_by_search_response]
|
54
|
+
# r = SearchResponse.new
|
55
|
+
# r.more = response[:more_campaign].to_i
|
56
|
+
# r.results = response[:campaign_infos]
|
57
|
+
# r
|
58
|
+
# end
|
59
|
+
|
60
|
+
# def getCountById(idType,ids,countType,status)
|
61
|
+
# operation = make_operation('getCountById')
|
62
|
+
# operation.header = operation_header
|
63
|
+
# operation.body = {
|
64
|
+
# :getCountByIdRequest=>{
|
65
|
+
# :idType=>idType.to_i,
|
66
|
+
# :ids=>ids,
|
67
|
+
# :countType=>countType.to_i,
|
68
|
+
# :status=>status.to_i
|
69
|
+
# }
|
70
|
+
# }
|
71
|
+
# response = operation.call
|
72
|
+
# if @debug
|
73
|
+
# puts operation.build
|
74
|
+
# end
|
75
|
+
# response.body
|
76
|
+
# end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/ext.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
class String
|
2
|
+
def snake_case
|
3
|
+
self.gsub(/::/, '/').
|
4
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
5
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
6
|
+
tr("-", "_").
|
7
|
+
downcase
|
8
|
+
end
|
9
|
+
end
|
10
|
+
class Savon
|
11
|
+
class Response
|
12
|
+
def header
|
13
|
+
hash[:envelope][:header]
|
14
|
+
end
|
15
|
+
def res_header
|
16
|
+
header[:res_header]
|
17
|
+
end
|
18
|
+
def desc
|
19
|
+
res_header[:desc]
|
20
|
+
end
|
21
|
+
def quota
|
22
|
+
res_header[:quota]
|
23
|
+
end
|
24
|
+
def rquota
|
25
|
+
res_header[:rquota]
|
26
|
+
end
|
27
|
+
def oprs
|
28
|
+
res_header[:oprs]
|
29
|
+
end
|
30
|
+
def oprtime
|
31
|
+
res_header[:oprtime]
|
32
|
+
end
|
33
|
+
def failures
|
34
|
+
res_header[:failures]
|
35
|
+
end
|
36
|
+
def code
|
37
|
+
failures[:code] if failures
|
38
|
+
end
|
39
|
+
def message
|
40
|
+
failures[:message] if failures
|
41
|
+
end
|
42
|
+
def status
|
43
|
+
res_header[:status]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/map_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
#coding:UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Baidu::Map do
|
5
|
+
subject {Baidu::Map}
|
6
|
+
describe "#get_cityid" do
|
7
|
+
it "查询北京应返回131" do
|
8
|
+
subject.get_cityid('北京').should == 131
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#coordinate" do
|
13
|
+
it "抓取北京医院信息,应返回正确经纬度数组" do
|
14
|
+
xy = subject.coordinate('北京医院',131)
|
15
|
+
xy.class.should == Array
|
16
|
+
# xy.each do |number|
|
17
|
+
# number.to_f.should > 0
|
18
|
+
# end
|
19
|
+
# xy.should == [116.421477, 39.910057]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Baidu::Map do
|
25
|
+
subject{Baidu::Map.new(BAIDU_MAP_KEY)}
|
26
|
+
let(:poi){subject.around(39.811031821584, 116.44931548023).within(1000)}
|
27
|
+
describe '#cafe' do
|
28
|
+
it "should return self when calling #cafe" do
|
29
|
+
subject.cafe.is_a? Baidu::Map
|
30
|
+
subject.bus.is_a? Baidu::Map
|
31
|
+
subject.bank.is_a? Baidu::Map
|
32
|
+
subject.spot.is_a? Baidu::Map
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#bus" do
|
37
|
+
it "抓取公交信息" do
|
38
|
+
# poi = subject.around(39.811031821584, 116.44931548023).within(1000)
|
39
|
+
bus = poi.bus.info
|
40
|
+
bus.class.should == HTTParty::Response
|
41
|
+
status = bus['status']
|
42
|
+
results = bus['results']
|
43
|
+
status.should == 0
|
44
|
+
results.class.should == Array
|
45
|
+
results.first.class.should == Hash
|
46
|
+
results.first['name'].should_not == nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#bank" do
|
51
|
+
it "抓取银行信息" do
|
52
|
+
# poi = subject.around(39.811031821584, 116.44931548023).within(1000)
|
53
|
+
bank = poi.bank.info
|
54
|
+
bank.class.should == HTTParty::Response
|
55
|
+
status = bank['status']
|
56
|
+
results = bank['results']
|
57
|
+
status.should == 0
|
58
|
+
results.class.should == Array
|
59
|
+
results.first.class.should == Hash
|
60
|
+
results.first['name'].should_not == nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#cafe" do
|
65
|
+
it "抓取餐馆信息" do
|
66
|
+
# poi = subject.around(39.811031821584, 116.44931548023).within(1000)
|
67
|
+
cafe = poi.cafe.info
|
68
|
+
cafe.class.should == HTTParty::Response
|
69
|
+
status = cafe['status']
|
70
|
+
results = cafe['results']
|
71
|
+
status.should == 0
|
72
|
+
results.class.should == Array
|
73
|
+
results.first.class.should == Hash
|
74
|
+
results.first['name'].should_not == nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|