seotracker 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -0
- data/README.rdoc +2 -0
- data/VERSION +1 -1
- data/lib/seotracker/yandex/direct.rb +30 -0
- data/lib/seotracker/yandex.rb +31 -14
- data/lib/seotracker.rb +15 -0
- data/seotracker.gemspec +3 -2
- data/spec/lib/seotracker_spec.rb +34 -9
- metadata +10 -9
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Seotracker::Yandex::Direct < Seotracker::Yandex
|
4
|
+
def special(word)
|
5
|
+
get_cookie
|
6
|
+
url = SEARCH_URL + "text=#{word}&p=0"
|
7
|
+
page = @agent.get(url, [], nil, {'cookie' => @cookie})
|
8
|
+
begin
|
9
|
+
texts = page.root.xpath('/html/body/div[3]/div/div/div/div/div[2]/div/h2/a')
|
10
|
+
hrefs = page.root.xpath('/html/body/div[3]/div/div/div/div/div/div/div/div/span')
|
11
|
+
|
12
|
+
# pre_result - массив вида ['text','text','text','url','url','url']
|
13
|
+
pre_result = []
|
14
|
+
texts.map { |t| pre_result << t.content.strip.squeeze("\n") }
|
15
|
+
hrefs.map { |h| pre_result << h.content.scan(/\w+\.\w+/).first unless h.content.scan(/\w+\.\w+/)== [] }
|
16
|
+
raise Seotracker::Yandex::Direct::Exception if pre_result.count != 6
|
17
|
+
|
18
|
+
# приводим pre_result к виду [{ad: text, url: url}}]
|
19
|
+
result = []
|
20
|
+
(0...3).to_a.each { |i| result << { ad: pre_result[i], url: pre_result[i + 3] } }
|
21
|
+
|
22
|
+
result
|
23
|
+
rescue Exception => e
|
24
|
+
debug "can't parse yandex direct:" + e.message
|
25
|
+
'error'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Seotracker::Yandex::Direct::Exception < Exception; end
|
data/lib/seotracker/yandex.rb
CHANGED
@@ -1,24 +1,41 @@
|
|
1
1
|
class Seotracker::Yandex < Seotracker
|
2
|
-
SEARCH_URL =
|
2
|
+
SEARCH_URL = 'http://yandex.ru/yandsearch?'
|
3
|
+
WORDSTAT_URL = 'http://wordstat.yandex.ru/?cmd=words&page=1&&geo=&text_geo=&text='
|
4
|
+
|
5
|
+
# получаем стастистику wordstat
|
6
|
+
# word - слово, по которому получаем статистику
|
7
|
+
def get_wordstat(word)
|
8
|
+
url = WORDSTAT_URL + word
|
9
|
+
get_cookie if @cookie.nil?
|
10
|
+
page = @agent.get(url, [], nil, {'cookie' => @cookie})
|
11
|
+
res = page.root.xpath('/html/body/form/table[2]/tbody/tr/td[4]/table/tbody/tr[3]/td/table/tbody/tr[2]/td[3]')
|
12
|
+
begin
|
13
|
+
res.first.content
|
14
|
+
rescue Exception => e
|
15
|
+
debug "can't get yandex wordstat:" + e.message
|
16
|
+
0
|
17
|
+
end
|
18
|
+
end
|
3
19
|
|
4
20
|
protected
|
5
21
|
|
6
22
|
def parse(word, start = 0)
|
7
23
|
start /= 10
|
24
|
+
get_cookie if @cookie.nil?
|
25
|
+
url = SEARCH_URL + "text=#{word}&p=#{start}"
|
26
|
+
page = @agent.get(url, [], nil, {'cookie' => @cookie})
|
8
27
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
28
|
+
begin
|
29
|
+
page.root.xpath('/html/body/div[3]/div/div/div[2]/ol/li/div/h2/a')
|
30
|
+
rescue Exception => e
|
31
|
+
debug "can't parse yandex:" + e.message
|
32
|
+
'error'
|
13
33
|
end
|
34
|
+
end
|
14
35
|
|
15
|
-
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
url = SEARCH_URL + "text=#{word}&p=#{start}"
|
20
|
-
|
21
|
-
page = @agent.get(url, [], nil, {'cookie' => @cookie})
|
22
|
-
page.root.xpath('/html/body/div[3]/div/div/div[2]/ol/li/div/h2/a')
|
36
|
+
def get_cookie
|
37
|
+
# у яндекса хитрая проверка на роботов
|
38
|
+
@agent.get('http://kiks.yandex.ru/su/')
|
39
|
+
@cookie = @agent.cookies.first
|
23
40
|
end
|
24
|
-
end
|
41
|
+
end
|
data/lib/seotracker.rb
CHANGED
@@ -11,6 +11,13 @@ class Seotracker
|
|
11
11
|
@agent.user_agent_alias = Seotracker::USER_AGENT
|
12
12
|
@agent.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
13
13
|
@agent.agent.http.retry_change_requests = true
|
14
|
+
|
15
|
+
@debug = true
|
16
|
+
|
17
|
+
if @debug
|
18
|
+
@log = Logger.new('log.txt')
|
19
|
+
#@agent.log = @log если надо логировать mechnize
|
20
|
+
end
|
14
21
|
end
|
15
22
|
|
16
23
|
def get_position(site, word)
|
@@ -18,6 +25,9 @@ class Seotracker
|
|
18
25
|
while (start < 200) && !found
|
19
26
|
links = parse(word, start)
|
20
27
|
start += RESULTS
|
28
|
+
|
29
|
+
break if links == 'error'
|
30
|
+
|
21
31
|
links.each do |l|
|
22
32
|
pos += 1
|
23
33
|
href = l.attribute('href').value.downcase
|
@@ -29,7 +39,12 @@ class Seotracker
|
|
29
39
|
end
|
30
40
|
found ? pos : 0
|
31
41
|
end
|
42
|
+
|
43
|
+
def debug(message)
|
44
|
+
@log.debug(message) if @debug
|
45
|
+
end
|
32
46
|
end
|
33
47
|
|
34
48
|
require 'seotracker/yandex'
|
49
|
+
require 'seotracker/yandex/direct'
|
35
50
|
require 'seotracker/google'
|
data/seotracker.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "seotracker"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["krivich ekaterina"]
|
12
|
-
s.date = "2012-04-
|
12
|
+
s.date = "2012-04-06"
|
13
13
|
s.description = "track sites position in google or yandex by keyword"
|
14
14
|
s.email = "kiote_the_one@mail.ru"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"lib/seotracker.rb",
|
27
27
|
"lib/seotracker/google.rb",
|
28
28
|
"lib/seotracker/yandex.rb",
|
29
|
+
"lib/seotracker/yandex/direct.rb",
|
29
30
|
"seotracker.gemspec",
|
30
31
|
"spec/lib/seotracker_spec.rb",
|
31
32
|
"spec/spec_helper.rb"
|
data/spec/lib/seotracker_spec.rb
CHANGED
@@ -2,15 +2,23 @@
|
|
2
2
|
$LOAD_PATH << File.expand_path('../../', __FILE__)
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
+
def yandex_mocker(mock)
|
6
|
+
mock.expect(:get, mock, ['http://kiks.yandex.ru/su/'])
|
7
|
+
mock.expect(:get, mock, [Seotracker::Yandex::SEARCH_URL + "text=#{@word}&p=0", [], nil, {'cookie' => 'hi'}])
|
8
|
+
mock.expect(:cookies, ['hi'])
|
9
|
+
end
|
10
|
+
|
11
|
+
def common_mocker
|
12
|
+
mock = MiniTest::Mock.new
|
13
|
+
mock.expect(:root, mock)
|
14
|
+
mock.expect(:attribute, mock, %w/href/)
|
15
|
+
mock.expect(:value, "http://#{@site}")
|
16
|
+
end
|
17
|
+
|
5
18
|
describe Seotracker do
|
6
19
|
# общие моки, тут от природной лени несколько объектов используют один мок
|
7
20
|
# что может несколько напрягать в дальнейшем
|
8
|
-
|
9
|
-
mock = MiniTest::Mock.new
|
10
|
-
mock.expect(:root, mock)
|
11
|
-
mock.expect(:attribute, mock, %w/href/)
|
12
|
-
mock.expect(:value, "http://#{@site}")
|
13
|
-
end
|
21
|
+
|
14
22
|
|
15
23
|
before do
|
16
24
|
@site = 'serialmaniak.ru'
|
@@ -23,9 +31,7 @@ describe Seotracker do
|
|
23
31
|
|
24
32
|
# мокаем все неважное
|
25
33
|
mock = common_mocker
|
26
|
-
|
27
|
-
mock.expect(:get, mock, ['http://kiks.yandex.ru/su/'])
|
28
|
-
mock.expect(:cookies, ['hi'])
|
34
|
+
yandex_mocker(mock)
|
29
35
|
mock.expect(:xpath, [mock], %w\/html/body/div[3]/div/div/div[2]/ol/li/div/h2/a\)
|
30
36
|
|
31
37
|
@object.instance_variable_set(:@agent, mock)
|
@@ -52,4 +58,23 @@ describe Seotracker do
|
|
52
58
|
@object.get_position(@site, @word).must_be :>, 0
|
53
59
|
end
|
54
60
|
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe Seotracker::Yandex::Direct do
|
64
|
+
before do
|
65
|
+
@client = Seotracker::Yandex::Direct.new
|
66
|
+
@word = 'окна'
|
67
|
+
|
68
|
+
mock =common_mocker
|
69
|
+
yandex_mocker(mock)
|
70
|
+
mock.expect(:xpath, [mock, mock, mock], %w\/html/body/div[3]/div/div/div/div/div[2]/div/h2/a\)
|
71
|
+
mock.expect(:xpath, [mock, mock, mock], %w\/html/body/div[3]/div/div/div/div/div/div/div/div/span\)
|
72
|
+
mock.expect(:content, 'yandex.ru')
|
73
|
+
|
74
|
+
@client.instance_variable_set(:@agent, mock)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should get valid special' do
|
78
|
+
@client.special(@word).count.must_equal 3
|
79
|
+
end
|
55
80
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seotracker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
16
|
-
requirement: &
|
16
|
+
requirement: &70312546860700 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70312546860700
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: mechanize
|
27
|
-
requirement: &
|
27
|
+
requirement: &70312546859880 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70312546859880
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jeweler
|
38
|
-
requirement: &
|
38
|
+
requirement: &70312546859300 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70312546859300
|
47
47
|
description: track sites position in google or yandex by keyword
|
48
48
|
email: kiote_the_one@mail.ru
|
49
49
|
executables: []
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- lib/seotracker.rb
|
62
62
|
- lib/seotracker/google.rb
|
63
63
|
- lib/seotracker/yandex.rb
|
64
|
+
- lib/seotracker/yandex/direct.rb
|
64
65
|
- seotracker.gemspec
|
65
66
|
- spec/lib/seotracker_spec.rb
|
66
67
|
- spec/spec_helper.rb
|
@@ -79,7 +80,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
80
|
version: '0'
|
80
81
|
segments:
|
81
82
|
- 0
|
82
|
-
hash: -
|
83
|
+
hash: -713848669405107154
|
83
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
85
|
none: false
|
85
86
|
requirements:
|