use Data::Printer;
use Text::Wrap;
use POSIX qw(strftime);
+use DateTime;
tie my $uuid, 'OSSP::uuid::tie';
$uuid= ["v1"];
(herc => {url => 'http://main.hercjobs.org/jobs/search?keywords=professor+AND+%28genomics+OR+bioinformatics+OR+biology+OR+informatics%29&discipline=academic-faculty&category=academic-faculty&category=allied-health&category=biological-biomedical-sciences&category=computer-information-sciences&category=education&category=interdisciplinary&category=mathematics-statistics&category=medical-research&category=physical-sciences&sort=DATE_POSTED+DESC',
next_selector => [class => "bti-pagination-previous-link bti-pagination-prev-next",text => '>'],
job_selector => [url_regex => qr{^\/jobs\/\d+/.+}],
- university => [itemprop=>"hiringOrganization",itemtype=>"http://schema.org/Organization"],
+ university => [itemprop=>"hiringOrganization",itemtype=> qr{https?://schema.org/Organization}],
description => [class=>"bti-jd-description",itemprop=>"description"],
date => [class=>"bti-jd-detail-text",
sub {scalar $_[0]->parent()->attr('class') eq 'bti-jd-details-action'}],
job_selector => [url_regex => qr{^/naturejobs/science/jobs/\d+-.+}],
university => [href => qr{^/naturejobs/science/employer-directory/\d+$}],
description => [class=>"job-description"],
- date => [],
+ date => [_tag => 'dd', sub {$_[0]->as_text() =~ qr/\d+\s+days\s+ago$/},],
position => [class=>'job-title heading'],
},
vitae => {url => 'https://chroniclevitae.com/job_search?job_search%5Bdistance_from_zip%5D=10&job_search%5Bemployment_type%5D=Full-time&job_search%5Bposition_type%5D=63',
job_selector => [url_regex => qr{/jobs/\d+-\d+$}],
university => [href => qr{/institutions/\d+$}],
description => [class => 'job-listing__content__description'],
- date => [_tag => 'td', content => qr/\,\s+20\d{2}$/],
+ date => [_tag => 'td', sub {$_[0]->as_text() =~ qr/\,\s+20\d{2}$/}],
position => [_tag => 'h1',
sub {defined $_[0]->parent()->attr('class') and
$_[0]->parent()->attr('class') eq
'page-title page-title--two-col'},
],
},
+ higheredjobs => {url => 'https://www.higheredjobs.com/search/advanced_action.cfm?JobCat=113&JobCat=259&JobCat=99&JobCat=100&JobCat=108&JobCat=107&PosType=1&InstType=1&InstType=2&InstType=3&Keyword=&Remote=1&Remote=2&Region=&Submit=Search+Jobs',
+ next_selector_tree => [class => 'js-click-submit',
+ href => qr{advanced_action\.cfm},
+ sub {return 1
+ if defined
+ $_[0]->look_down(src =>
+ qr/active-right/);
+ return 0;
+ },
+ ],
+ job_selector => [url_regex => qr{^details.cfm\?JobCode=\d+},
+ ],
+ university => [class => qr/field-value/,
+ sub {my $p = $_[0]->parent();
+ my $c = $p->look_down(class => qr/field-label/,
+ );
+ defined $c and $c->as_text() =~ qr/institution/i;
+ }
+ ],
+ date => [class => qr/field-value/,
+ sub {my $p = $_[0]->parent();
+ my $c = $p->look_down(class => qr/field-label/,
+ );
+ defined $c and $c->as_text() =~ qr/posted/i;
+ }
+ ],
+ position => [id => 'jobtitle-header',
+ _tag => 'h1',
+ ],
+ description => [id => 'jobDesc'],
+ },
);
binmode STDOUT,":utf8";
if (not defined $sites{$site}) {
die "Unknown site $site";
}
+ print "* Jobs from $site\n";
my $s = $sites{$site};
$m->get($s->{url});
for (1..$pages) {
my %seen;
my @job_urls = grep { ! $seen{ $_->URI()->abs() }++ }
$m->find_all_links(@{$s->{job_selector}});
- for my $j_u (@job_urls) {
+ my $link;
+ if (exists $s->{next_selector}) {
+ ($link) = map {$_->URI()->abs()}
+ $m->find_all_links(@{$s->{next_selector}});
+ } elsif (exists $s->{next_selector_tree}) {
+ $link = $m->tree->look_down(@{$s->{next_selector_tree}});
+ if (not defined $link) {
+ $m->tree->dump;
+ }
+ die "Unable to find next link" unless defined $link;
+ $link = $link->attr('href');
+ }
+ for my $j_u (sort @job_urls) {
$m->get($j_u) or next;
my $university = 'No university';
eval {
eval {
$date = $m->tree->look_down(@{$s->{date}})->as_text() // $todays_date if
@{$s->{date}};
+ if ($date =~ /^\s*(\d+)\s*days\s*ago\s*$/) {
+ $date = strftime('%Y-%m-%d %H:%M:%S',
+ localtime((DateTime->now() -
+ DateTime::Duration->new(days=>$1))->epoch));
+ }
};
my $description = 'unknown';
eval {
$position = $m->tree->look_down(@{$s->{position}})->as_text();
};
print format_job($university,$position,$j_u->URI->abs(),$description,$date);
- $m->back();
+ $m->back() or die "Unable to go back";
}
- $m->follow_link(@{$s->{next_selector}}) or die "Unable to find next link";
+ $m->get($link);
}
}