Fix code and delete unnecessary files CSS

parent 8d1b59bc
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -48,35 +48,3 @@ p { ...@@ -48,35 +48,3 @@ p {
height: 100px; height: 100px;
position: relative; position: relative;
} }
.float-right {
position: absolute;
bottom: 0;
right: 5%;
}
.top-page{
text-align: center;
width: 100%;
height: 100%;
}
.total-job{
position: absolute;
color: white;
top: 40%;
right: 30%;
font-size: 60px;
}
.banner-ground{
position: relative;
width: 100%;
height: 50vh;
}
.top-banner {
background-image: url('banner.jpg');
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size: cover;
}
.salary{
color: green;
}
\ No newline at end of file
/*!
* Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
svg:not(:root).svg-inline--fa {
overflow: visible; }
.svg-inline--fa {
display: inline-block;
font-size: inherit;
height: 1em;
overflow: visible;
vertical-align: -.125em; }
.svg-inline--fa.fa-lg {
vertical-align: -.225em; }
.svg-inline--fa.fa-w-1 {
width: 0.0625em; }
.svg-inline--fa.fa-w-2 {
width: 0.125em; }
.svg-inline--fa.fa-w-3 {
width: 0.1875em; }
.svg-inline--fa.fa-w-4 {
width: 0.25em; }
.svg-inline--fa.fa-w-5 {
width: 0.3125em; }
.svg-inline--fa.fa-w-6 {
width: 0.375em; }
.svg-inline--fa.fa-w-7 {
width: 0.4375em; }
.svg-inline--fa.fa-w-8 {
width: 0.5em; }
.svg-inline--fa.fa-w-9 {
width: 0.5625em; }
.svg-inline--fa.fa-w-10 {
width: 0.625em; }
.svg-inline--fa.fa-w-11 {
width: 0.6875em; }
.svg-inline--fa.fa-w-12 {
width: 0.75em; }
.svg-inline--fa.fa-w-13 {
width: 0.8125em; }
.svg-inline--fa.fa-w-14 {
width: 0.875em; }
.svg-inline--fa.fa-w-15 {
width: 0.9375em; }
.svg-inline--fa.fa-w-16 {
width: 1em; }
.svg-inline--fa.fa-w-17 {
width: 1.0625em; }
.svg-inline--fa.fa-w-18 {
width: 1.125em; }
.svg-inline--fa.fa-w-19 {
width: 1.1875em; }
.svg-inline--fa.fa-w-20 {
width: 1.25em; }
.svg-inline--fa.fa-pull-left {
margin-right: .3em;
width: auto; }
.svg-inline--fa.fa-pull-right {
margin-left: .3em;
width: auto; }
.svg-inline--fa.fa-border {
height: 1.5em; }
.svg-inline--fa.fa-li {
width: 2em; }
.svg-inline--fa.fa-fw {
width: 1.25em; }
.fa-layers svg.svg-inline--fa {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0; }
.fa-layers {
display: inline-block;
height: 1em;
position: relative;
text-align: center;
vertical-align: -.125em;
width: 1em; }
.fa-layers svg.svg-inline--fa {
-webkit-transform-origin: center center;
transform-origin: center center; }
.fa-layers-text, .fa-layers-counter {
display: inline-block;
position: absolute;
text-align: center; }
.fa-layers-text {
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transform-origin: center center;
transform-origin: center center; }
.fa-layers-counter {
background-color: #ff253a;
border-radius: 1em;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: #fff;
height: 1.5em;
line-height: 1;
max-width: 5em;
min-width: 1.5em;
overflow: hidden;
padding: .25em;
right: 0;
text-overflow: ellipsis;
top: 0;
-webkit-transform: scale(0.25);
transform: scale(0.25);
-webkit-transform-origin: top right;
transform-origin: top right; }
.fa-layers-bottom-right {
bottom: 0;
right: 0;
top: auto;
-webkit-transform: scale(0.25);
transform: scale(0.25);
-webkit-transform-origin: bottom right;
transform-origin: bottom right; }
.fa-layers-bottom-left {
bottom: 0;
left: 0;
right: auto;
top: auto;
-webkit-transform: scale(0.25);
transform: scale(0.25);
-webkit-transform-origin: bottom left;
transform-origin: bottom left; }
.fa-layers-top-right {
right: 0;
top: 0;
-webkit-transform: scale(0.25);
transform: scale(0.25);
-webkit-transform-origin: top right;
transform-origin: top right; }
.fa-layers-top-left {
left: 0;
right: auto;
top: 0;
-webkit-transform: scale(0.25);
transform: scale(0.25);
-webkit-transform-origin: top left;
transform-origin: top left; }
.fa-lg {
font-size: 1.33333em;
line-height: 0.75em;
vertical-align: -.0667em; }
.fa-xs {
font-size: .75em; }
.fa-sm {
font-size: .875em; }
.fa-1x {
font-size: 1em; }
.fa-2x {
font-size: 2em; }
.fa-3x {
font-size: 3em; }
.fa-4x {
font-size: 4em; }
.fa-5x {
font-size: 5em; }
.fa-6x {
font-size: 6em; }
.fa-7x {
font-size: 7em; }
.fa-8x {
font-size: 8em; }
.fa-9x {
font-size: 9em; }
.fa-10x {
font-size: 10em; }
.fa-fw {
text-align: center;
width: 1.25em; }
.fa-ul {
list-style-type: none;
margin-left: 2.5em;
padding-left: 0; }
.fa-ul > li {
position: relative; }
.fa-li {
left: -2em;
position: absolute;
text-align: center;
width: 2em;
line-height: inherit; }
.fa-border {
border: solid 0.08em #eee;
border-radius: .1em;
padding: .2em .25em .15em; }
.fa-pull-left {
float: left; }
.fa-pull-right {
float: right; }
.fa.fa-pull-left,
.fas.fa-pull-left,
.far.fa-pull-left,
.fal.fa-pull-left,
.fab.fa-pull-left {
margin-right: .3em; }
.fa.fa-pull-right,
.fas.fa-pull-right,
.far.fa-pull-right,
.fal.fa-pull-right,
.fab.fa-pull-right {
margin-left: .3em; }
.fa-spin {
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear; }
.fa-pulse {
-webkit-animation: fa-spin 1s infinite steps(8);
animation: fa-spin 1s infinite steps(8); }
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
.fa-rotate-90 {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
-webkit-transform: rotate(90deg);
transform: rotate(90deg); }
.fa-rotate-180 {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
-webkit-transform: rotate(180deg);
transform: rotate(180deg); }
.fa-rotate-270 {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
-webkit-transform: rotate(270deg);
transform: rotate(270deg); }
.fa-flip-horizontal {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
-webkit-transform: scale(-1, 1);
transform: scale(-1, 1); }
.fa-flip-vertical {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
-webkit-transform: scale(1, -1);
transform: scale(1, -1); }
.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
-webkit-transform: scale(-1, -1);
transform: scale(-1, -1); }
:root .fa-rotate-90,
:root .fa-rotate-180,
:root .fa-rotate-270,
:root .fa-flip-horizontal,
:root .fa-flip-vertical,
:root .fa-flip-both {
-webkit-filter: none;
filter: none; }
.fa-stack {
display: inline-block;
height: 2em;
position: relative;
width: 2.5em; }
.fa-stack-1x,
.fa-stack-2x {
bottom: 0;
left: 0;
margin: auto;
position: absolute;
right: 0;
top: 0; }
.svg-inline--fa.fa-stack-1x {
height: 1em;
width: 1.25em; }
.svg-inline--fa.fa-stack-2x {
height: 2em;
width: 2.5em; }
.fa-inverse {
color: #fff; }
.sr-only {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px; }
.sr-only-focusable:active, .sr-only-focusable:focus {
clip: auto;
height: auto;
margin: 0;
overflow: visible;
position: static;
width: auto; }
.svg-inline--fa .fa-primary {
fill: var(--fa-primary-color, currentColor);
opacity: 1;
opacity: var(--fa-primary-opacity, 1); }
.svg-inline--fa .fa-secondary {
fill: var(--fa-secondary-color, currentColor);
opacity: 0.4;
opacity: var(--fa-secondary-opacity, 0.4); }
.svg-inline--fa.fa-swap-opacity .fa-primary {
opacity: 0.4;
opacity: var(--fa-secondary-opacity, 0.4); }
.svg-inline--fa.fa-swap-opacity .fa-secondary {
opacity: 1;
opacity: var(--fa-primary-opacity, 1); }
.svg-inline--fa mask .fa-primary,
.svg-inline--fa mask .fa-secondary {
fill: black; }
.fad.fa-inverse {
color: #fff; }
/*!
* Font Awesome Free 5.14.0 by @fontawesome - https://fontawesome.com
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
*/
.svg-inline--fa,svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-webkit-transform:scaleY(-1);transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1);transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor)}.svg-inline--fa .fa-secondary,.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fad.fa-inverse{color:#fff}
\ No newline at end of file
// Place all the styles related to the Top_pages controller here. // Place all the styles related to the Top_pages controller here.
// They will automatically be included in application.css. // They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/ // You can use Sass (SCSS) here: http://sass-lang.com/
.float-right {
position: absolute;
bottom: 0;
right: 5%;
}
.top-page{
text-align: center;
width: 100%;
height: 100%;
}
.total-job{
position: absolute;
color: white;
top: 40%;
right: 30%;
font-size: 60px;
}
.banner-ground{
position: relative;
width: 100%;
height: 50vh;
}
.top-banner {
background-image: url('banner.jpg');
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size: cover;
}
.salary{
color: green;
}
.job-details{
position: relative;
padding: 15px;
margin: 10px;
}
#button-follow{
position: absolute;
top: 20%;
right: 5%;
}
\ No newline at end of file
class TopPagesController < ApplicationController class TopPagesController < ApplicationController
def index def index
@total = Job.ids @total_jobs = Job.ids
end @jobs = Job.limit(5).order(created_at: :desc)
def show @companies = Company.all
@job = Job.all.order(created_at: :desc) @total_cities = CityJob.all.group('city_id').count
@company = Company.all
end end
end end
...@@ -14,4 +14,9 @@ class Job < ApplicationRecord ...@@ -14,4 +14,9 @@ class Job < ApplicationRecord
has_many :histories has_many :histories
has_many :users, through: :histories has_many :users, through: :histories
def company_name
@company_name ||= company&.name
end
end end
class TopPage < ApplicationRecord
end
<% @jobs.each do |job| %>
<% if job.cities.present? %>
<div class="border border-dark rounded">
<div class="job-details">
<div class="title"><strong><%= job.title %></strong></div>
<div><%= job.company_name %></div>
<div class="salary"><i class="fas fa-dollar-sign"></i>Lương: <%= job.salary %></div>
<div><i class="fas fa-map-marker"></i>
<% job.cities.each do |city| %>
<%= city.name %>
<% end %>
</div>
<button type="button" class="btn btn-primary" id="button-follow"><i class="fas fa-heart"></i> Follow</button>
</div>
</div>
<br>
<% end %>
<% end %>
\ No newline at end of file
...@@ -10,13 +10,10 @@ ...@@ -10,13 +10,10 @@
<%= stylesheet_link_tag 'bootstrap', media: 'all', 'data-turbolinks-track': 'reload' %> <%= stylesheet_link_tag 'bootstrap', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'bootstrap', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'bootstrap', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'https://kit.fontawesome.com/yourcode.js', media: 'all', 'data-turbolinks-track': 'reload' %>
</head> </head>
<body> <body>
<%= render "layouts/header" %> <%= render "layouts/header" %>
<%= yield %> <%= yield %>
<%= render "layouts/footer" %> <%= render "layouts/footer" %>
</body> </body>
</html> </html>
<% provide(:title, 'Venjob') %> <% provide(:title, 'Venjob') %>
<div class="banner-ground"> <div class="banner-ground">
<div class="top-banner"> <div class="top-banner">
<div class="total-job">total: <%= @total.count %> Jobs</div> <div class="total-job">total: <%= @total_jobs.count %> Jobs</div>
</div> </div>
</div> </div>
<div><%#= render 'top_pages/show' %></div> <div class="container">
<div class="job-list"><%= render 'layouts/show_jobs' %></div>
</div>
<% provide(:title, 'All jobs') %>
<% @job.each do |job| %>
<% if !job.cities.blank? %>
<ul>
<div class="title"><strong><%= job.title %></strong></div>
<div><%= (@company.find_by(id: job.company_id)).name %></div>
<div class="salary"><i class="fas fa-dollar-sign"></i>Lương: <%= job.salary %></div>
<div><i class="fas fa-map-marker"></i>
<% job.cities.each do |location| %>
<%= location.name %>
<% end %>
</div>
</ul>
<% end %>
<% end %>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
class Crawler class Crawler
def initialize(logger) def initialize(logger)
@mylogger = logger @mylogger = logger
@NAME_DOMAIN = '192.168.1.156'
@USERNAME_FTP = 'training'
@PASSWORD_FTP = 'training'
end end
def crawl_city def crawl_city
page = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-vi.html")) page = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-vi.html"))
get_name = page.search('select#location') get_name = page.search('select#location')
...@@ -34,26 +38,21 @@ class Crawler ...@@ -34,26 +38,21 @@ class Crawler
company_info = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-trang-#{n}-vi.html")) company_info = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-trang-#{n}-vi.html"))
company_link = company_info.css('div.caption a.company-name').map{ |link| link['href'] } company_link = company_info.css('div.caption a.company-name').map{ |link| link['href'] }
company_link.each do |link| company_link.each do |link|
if link.include?('\u2019') next if link == 'javascript:void(0);'
link.gsub!('\u2019',"'") company_page = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link))))
end if !(company_page.search('p.name').text).nil?
next if link == 'javascript:void(0);' begin
if link != 'https://careerbuilder.vn/vi/nha-tuyen-dung/hr-vietnam\xE2\x80\x99s-ess-client.35A4EFBA.html' name_company = company_page.search('p.name').text
company_page = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link)))) address_company = company_page.css('div.content p').children[1].text
if !(company_page.search('p.name').text).nil? introduction_company = company_page.css('div.main-about-us').text
begin get_name_company = Company.find_by(name: name_company)
name_company = company_page.search('p.name').text if get_name_company.nil?
address_company = company_page.css('div.content p').children[1].text company = Company.create!(name: name_company,
introduction_company = company_page.css('div.main-about-us').text address: address_company,
get_name_company = Company.find_by(name: name_company) introduction: introduction_company)
if get_name_company.nil?
company = Company.create!(name: name_company,
address: address_company,
introduction: introduction_company)
end
rescue StandardError => e
@mylogger.error "#{e.message}"
end end
rescue StandardError => e
@mylogger.error "#{e.message}"
end end
end end
end end
...@@ -67,7 +66,7 @@ class Crawler ...@@ -67,7 +66,7 @@ class Crawler
get_link.each do |link| get_link.each do |link|
page_job = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link)))) page_job = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link))))
get_row = page_job.search('div.bg-blue div.row') get_row = page_job.search('div.bg-blue div.row')
if get_row != "" if get_row.present?
begin begin
get_name_company = page_job.search('div.job-desc a.job-company-name').text.strip get_name_company = page_job.search('div.job-desc a.job-company-name').text.strip
company_table = Company.find_by(name: get_name_company) company_table = Company.find_by(name: get_name_company)
...@@ -79,7 +78,7 @@ class Crawler ...@@ -79,7 +78,7 @@ class Crawler
experience = get_row.at_xpath('//li[./strong/i[contains(@class, "fa fa-briefcase")]]/p').text.strip experience = get_row.at_xpath('//li[./strong/i[contains(@class, "fa fa-briefcase")]]/p').text.strip
level = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-account")]]/p').text.strip level = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-account")]]/p').text.strip
expiration_date = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-calendar-check")]]/p').text.strip expiration_date = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-calendar-check")]]/p').text.strip
if job_check.nil? if job_check.blank?
job = Job.create!(title: title_job, job = Job.create!(title: title_job,
level: level, level: level,
salary: salary, salary: salary,
...@@ -90,11 +89,12 @@ class Crawler ...@@ -90,11 +89,12 @@ class Crawler
end end
find_job = Job.find_by(title: title_job, company_id: company_table.id) find_job = Job.find_by(title: title_job, company_id: company_table.id)
puts find_job.title puts find_job.title
unless find_job.nil? if find_job.present?
location_rel = get_row.css('div.map p a').children.map { |location| location.text.strip } location_rel = get_row.css('div.map p a').children.map { |location| location.text.strip }
location_rel.each do |loc| location_rel.each do |loc|
city_table = City.find_by(name: loc) city_table = City.find_by(name: loc)
if CityJob.find_by(job_id: find_job.id, city_id: city_table.id).nil? next if city_table.nil?
unless CityJob.exists?(job_id: find_job.id, city_id: city_table.id).nil?
puts "Created City: #{find_job.id} - #{city_table.id}.#{loc}" puts "Created City: #{find_job.id} - #{city_table.id}.#{loc}"
city_jobs = CityJob.create!(job_id: find_job.id, city_id: city_table.id) city_jobs = CityJob.create!(job_id: find_job.id, city_id: city_table.id)
end end
...@@ -102,14 +102,15 @@ class Crawler ...@@ -102,14 +102,15 @@ class Crawler
industry_rel = get_row.css('li a').children.map { |industry| industry.text.strip } industry_rel = get_row.css('li a').children.map { |industry| industry.text.strip }
industry_rel.each do |ind| industry_rel.each do |ind|
industry_table = Industry.find_by(name: ind) industry_table = Industry.find_by(name: ind)
if IndustryJob.find_by(job_id: find_job.id, industry_id: industry_table.id).nil? next if industry_table.nil?
unless IndustryJob.exists?(job_id: find_job.id, industry_id: industry_table.id)
puts "Created Industry: #{find_job.id} - #{industry_table.id}.#{ind}" puts "Created Industry: #{find_job.id} - #{industry_table.id}.#{ind}"
industry_jobs = IndustryJob.create!(job_id: find_job.id, industry_id: industry_table.id) industry_jobs = IndustryJob.create!(job_id: find_job.id, industry_id: industry_table.id)
end end
end end
end end
rescue StandardError => e rescue StandardError => e
@mylogger.error "#{e.message}" @mylogger.error "#{e.message}"
end end
end end
end end
...@@ -117,7 +118,7 @@ class Crawler ...@@ -117,7 +118,7 @@ class Crawler
end end
def get_file_csv def get_file_csv
Net::FTP.open('192.168.1.156', 'training', 'training') do |ftp| Net::FTP.open(@NAME_DOMAIN, @USERNAME_FTP, @PASSWORD_FTP) do |ftp|
ftp.getbinaryfile('jobs.zip') ftp.getbinaryfile('jobs.zip')
end end
end end
......
...@@ -5,25 +5,23 @@ class Crontab ...@@ -5,25 +5,23 @@ class Crontab
def find_company def find_company
company_info = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-trang-1-vi.html")) company_info = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-trang-1-vi.html"))
company_link = company_info.css('div.caption a.company-name').map { |link| link['href'] } company_links = company_info.css('div.caption a.company-name').map { |link| link['href'] }
company_link.each do |link| company_links.each do |link|
next if link == 'javascript:void(0);' next if link == 'javascript:void(0);'
if link != 'https://careerbuilder.vn/vi/nha-tuyen-dung/hr-vietnam\xE2\x80\x99s-ess-client.35A4EFBA.html' company_page = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link))))
company_page = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link)))) if (company_page.search('p.name').text).present?
unless (company_page.search('p.name').text).nil? begin
begin name_company = company_page.search('p.name').text
name_company = company_page.search('p.name').text address_company = company_page.css('div.content p').children[1].text
address_company = company_page.css('div.content p').children[1].text introduction_company = company_page.css('div.main-about-us').text
introduction_company = company_page.css('div.main-about-us').text get_name_company = Company.find_by(name: name_company)
get_name_company = Company.find_by(name: name_company) if get_name_company.nil?
if get_name_company.nil? company = Company.create!(name: name_company,
company = Company.create!(name: name_company, address: address_company,
address: address_company, introduction: introduction_company)
introduction: introduction_company)
end
rescue StandardError => e
@mylogger.error "#{e.message}"
end end
rescue StandardError => e
@mylogger.error "#{e.message}"
end end
end end
end end
...@@ -34,7 +32,7 @@ class Crontab ...@@ -34,7 +32,7 @@ class Crontab
get_link.each do |link| get_link.each do |link|
page_job = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link)))) page_job = Nokogiri::HTML(URI.open(URI.parse(URI.escape(link))))
get_row = page_job.search('div.bg-blue div.row') get_row = page_job.search('div.bg-blue div.row')
if get_row != "" if get_row.present?
begin begin
get_name_company = page_job.search('div.job-desc a.job-company-name').text.strip get_name_company = page_job.search('div.job-desc a.job-company-name').text.strip
company_table = Company.find_by(name: get_name_company) company_table = Company.find_by(name: get_name_company)
...@@ -46,7 +44,7 @@ class Crontab ...@@ -46,7 +44,7 @@ class Crontab
experience = get_row.at_xpath('//li[./strong/i[contains(@class, "fa fa-briefcase")]]/p').text.strip experience = get_row.at_xpath('//li[./strong/i[contains(@class, "fa fa-briefcase")]]/p').text.strip
level = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-account")]]/p').text.strip level = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-account")]]/p').text.strip
expiration_date = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-calendar-check")]]/p').text.strip expiration_date = get_row.at_xpath('//li[./strong/i[contains(@class, "mdi mdi-calendar-check")]]/p').text.strip
if job_check.nil? if job_check.blank?
job = Job.create!(title: title_job, job = Job.create!(title: title_job,
level: level, level: level,
salary: salary, salary: salary,
...@@ -57,11 +55,12 @@ class Crontab ...@@ -57,11 +55,12 @@ class Crontab
end end
find_job = Job.find_by(title: title_job, company_id: company_table.id) find_job = Job.find_by(title: title_job, company_id: company_table.id)
puts find_job.title puts find_job.title
unless find_job.nil? if find_job.present?
location_rel = get_row.css('div.map p a').children.map { |location| location.text.strip } location_rel = get_row.css('div.map p a').children.map { |location| location.text.strip }
location_rel.each do |loc| location_rel.each do |loc|
city_table = City.find_by(name: loc) city_table = City.find_by(name: loc)
if CityJob.find_by(job_id: find_job.id, city_id: city_table.id).nil? next if city_table.nil?
unless CityJob.exists?(job_id: find_job.id, city_id: city_table.id).nil?
puts "Created City: #{find_job.id} - #{city_table.id}.#{loc}" puts "Created City: #{find_job.id} - #{city_table.id}.#{loc}"
city_jobs = CityJob.create!(job_id: find_job.id, city_id: city_table.id) city_jobs = CityJob.create!(job_id: find_job.id, city_id: city_table.id)
end end
...@@ -69,7 +68,8 @@ class Crontab ...@@ -69,7 +68,8 @@ class Crontab
industry_rel = get_row.css('li a').children.map { |industry| industry.text.strip } industry_rel = get_row.css('li a').children.map { |industry| industry.text.strip }
industry_rel.each do |ind| industry_rel.each do |ind|
industry_table = Industry.find_by(name: ind) industry_table = Industry.find_by(name: ind)
if IndustryJob.find_by(job_id: find_job.id, industry_id: industry_table.id).nil? next if industry_table.nil?
unless IndustryJob.exists?(job_id: find_job.id, industry_id: industry_table.id)
puts "Created Industry: #{find_job.id} - #{industry_table.id}.#{ind}" puts "Created Industry: #{find_job.id} - #{industry_table.id}.#{ind}"
industry_jobs = IndustryJob.create!(job_id: find_job.id, industry_id: industry_table.id) industry_jobs = IndustryJob.create!(job_id: find_job.id, industry_id: industry_table.id)
end end
......
...@@ -24,6 +24,6 @@ namespace :import do ...@@ -24,6 +24,6 @@ namespace :import do
crontab.find_job crontab.find_job
action.get_file_csv action.get_file_csv
action.extract_zip('./jobs.zip', 'lib/csv') action.extract_zip('./jobs.zip', 'lib/csv')
action.import_file_csv('lib/csv') action.import_file_csv(Rails.root.join('lib', 'csv', 'jobs.csv'))
end end
end end
require 'test_helper'
class TopPagesControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
end
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
# This model initially had no columns defined. If you add columns to the
# model remove the '{}' from the fixture names and add the columns immediately
# below each fixture, per the syntax in the comments below
#
one: {}
# column: value
#
two: {}
# column: value
require 'test_helper'
class TopPageTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment