Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)
Dalam tutorial ini, Anda akan belajar bagaimana Anda bisa menggunakan Mechanize untuk mengklik tautan, mengisi formulir, dan mengunggah file. Anda juga akan belajar bagaimana Anda bisa mengiris halaman objek Mechanize dan bagaimana cara mengotomatisasi pencarian Google dan menyimpan hasilnya.
Topik-topik
- Halaman Tunggal vs. Paginasi
- Mechanize
- Agen
- Halaman
- Metode Nokogiri
- Tautan-tautan
- Klik
- Formulir
Halaman Tunggal vs. Paginasi
Sejauh ini kita telah menghabiskan beberapa waktu mencari tahu bagaimana kita bisa meng-scrape layar satu halaman menggunakan Nokogiri. Ini adalah dasar yang baik untuk melangkah maju dan belajar mengekstrak konten dari banyak halaman.
Bagaimanapun, masalah yang ingin kita selesaikan melibatkan mendapatkan konten dari lebih dari 140 episode—yang lebih banyak konten daripada yang cukup sesuai dengan satu halaman web. Kita harus bekerja dengan paginasi dan perlu mencari cara untuk mengikuti konten di lubang kelincinya.
Di sinilah Nokogiri berhenti dan gem berguna lainnya yang disebut Mechanize ikut bermain.
Mechanize
Mechanize adalah alat lain yang hebat yang memiliki banyak barang untuk ditawarkan. Ini pada dasarnya memungkinkan Anda untuk mengotomatisasi interaksi dengan situs web yang Anda butuhkan untuk mengekstrak kontennya. Dalam hal ini, saya mengingatkan beberapa fungsi yang mungkin Anda ketahui dari pengujian dengan Capybara.
Jangan salah sangka, bermain dengan Nokogiri di satu halaman sangat mengagumkan, tapi untuk pekerjaan ekstraksi data yang lebih pedas, kita memerlukan sedikit tenaga kuda lagi. Pada intinya kita dapat merayap melalui halaman sebanyak yang kita butuhkan dan berinteraksi dengan elemen mereka—meniru dan mengotomatisasi perilaku manusia. Barang yang cukup bagus!
Permata ini memungkinkan Anda mengikuti tautan, mengisi field-field formulir, dan mengirimkan data tersebut—bahkan menangani cookie sudah dipersiapkan. Itu berarti Anda juga dapat meniru login pengguna ke sesi pribadi dan mendapatkan konten dari situs yang hanya Anda yang memiliki aksesnya.
Anda mengisi login dengan kredensial Anda dan memberitahu Mechanize bagaimana cara mengikuti. Karena Anda bisa mengklik tautan dan mengirimkan formulir, sangat sedikit yang tidak dapat Anda lakukan dengan alat ini. Ini memiliki hubungan dekat dengan Nokogiri dan juga bergantung padanya. Aaron Patterson kembali menjadi salah satu pencipta gem yang indah ini.
Instansiasi Agen Mechanize
Sebelum kita bisa mulai melakukan mekanisasi, kita perlu memberi instansiasi agen Mechanize.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
Agent
ini akan digunakan untuk mengambil halaman, mirip dengan apa yang kita lakukan dengan Nokogiri.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
Yang terjadi di sini adalah agen Mechanize mendapatkan halaman podcast dan cookies-nya.
Mengekstrak Konten Halaman
Kita sekarang memiliki halaman yang siap untuk diekstraksi. Sebelum kita melakukannya, saya menyarankan agar kita melihat apa yang terjadi dengan menggunakan metode inspect
.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
puts page.inspect |
Hasilnya cukup substantif. Lihat dan perhatikan apa arti objek Mechanize::Page
. Di sini Anda bisa melihat semua atribut untuk halaman itu.
Bagi saya, ini adalah objek yang sangat berguna untuk mengiris data yang ingin Anda ekstrak.
Keluaran
1 |
#<Mechanize::Page
|
2 |
{url #http://betweenscreens.fm/>} |
3 |
{meta_refresh} |
4 |
{title "Between | Screens "} |
5 |
{iframes
|
6 |
#<Mechanize::Page::Frame
|
7 |
nil |
8 |
"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/290328784&color=ff0000&auto...>
|
9 |
#<Mechanize::Page::Frame
|
10 |
nil
|
11 |
"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/290126141&color=ff0000&auto...> |
12 |
#<Mechanize::Page::Frame
|
13 |
nil |
14 |
"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/289018386&color=ff0000&auto...>
|
15 |
#<Mechanize::Page::Frame
|
16 |
nil
|
17 |
"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/287425105&color=ff0000&auto...> |
18 |
#<Mechanize::Page::Frame
|
19 |
nil |
20 |
"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/287105342&color=ff0000&auto...>
|
21 |
#<Mechanize::Page::Frame
|
22 |
nil
|
23 |
"https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/221003494&color=ff0000&auto...> |
24 |
#<Mechanize::Page::Frame
|
25 |
nil |
26 |
"">https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/218101809&color=ff0000&auto...} |
27 |
{frames} |
28 |
{links
|
29 |
#<Mechanize::Page::Link "Logo cube" "/">
|
30 |
#https://github.com/vis-kid/betweenscreens">
|
31 |
#<Mechanize::Page::Link "about" "pages/about/">
|
32 |
#<Mechanize::Page::Link "design" "design/">
|
33 |
#<Mechanize::Page::Link "code" "code/">
|
34 |
#<Mechanize::Page::Link "Randy J. Hunt" "episodes/144/">
|
35 |
#<Mechanize::Page::Link "Jason Long" "episodes/143/">
|
36 |
#<Mechanize::Page::Link "David Heinemeier Hansson" "episodes/142/">
|
37 |
#<Mechanize::Page::Link "Zach Holman" "episodes/141/">
|
38 |
#<Mechanize::Page::Link "Joel Glovier" "episodes/140/">
|
39 |
#<Mechanize::Page::Link "João Ferreira" "episodes/139/">
|
40 |
#<Mechanize::Page::Link "Corwin Harrell" "episodes/138/">
|
41 |
#<Mechanize::Page::Link "Older Stuff »" "page/2/">
|
42 |
#<Mechanize::Page::Link "Exercise" "/tags/exercise/">
|
43 |
#<Mechanize::Page::Link "Company benefits" "/tags/company-benefits/">
|
44 |
#<Mechanize::Page::Link "Tmux" "/tags/tmux/">
|
45 |
#<Mechanize::Page::Link "FileTask" "/tags/filetask/">
|
46 |
#<Mechanize::Page::Link "Decision making" "/tags/decision-making/">
|
47 |
#<Mechanize::Page::Link "Favorite feature" "/tags/favorite-feature/">
|
48 |
#<Mechanize::Page::Link "Working out" "/tags/working-out/">
|
49 |
#<Mechanize::Page::Link "Scott Savarie" "/tags/scott-savarie/">
|
50 |
#<Mechanize::Page::Link "Titles" "/tags/titles/">
|
51 |
#<Mechanize::Page::Link "Erik Spiekermann" "/tags/erik-spiekermann/">
|
52 |
#<Mechanize::Page::Link "Newbie mistakes" "/tags/newbie-mistakes/">
|
53 |
#<Mechanize::Page::Link "Playbook" "/tags/playbook/">
|
54 |
#<Mechanize::Page::Link "Delegation" "/tags/delegation/">
|
55 |
#<Mechanize::Page::Link "Heat maps" "/tags/heat-maps/">
|
56 |
#<Mechanize::Page::Link "Europe" "/tags/europe/">
|
57 |
#<Mechanize::Page::Link "Sizing type" "/tags/sizing-type/">
|
58 |
#<Mechanize::Page::Link "Focus" "/tags/focus/">
|
59 |
#<Mechanize::Page::Link "Virtual assistants" "/tags/virtual-assistants/">
|
60 |
#<Mechanize::Page::Link "Writing" "/tags/writing/">
|
61 |
#<Mechanize::Page::Link "Hacking" "/tags/hacking/">
|
62 |
#<Mechanize::Page::Link "Joel Glovier" "/tags/joel-glovier/">
|
63 |
#<Mechanize::Page::Link "Corwin Harrell" "/tags/corwin-harrell/">
|
64 |
#<Mechanize::Page::Link "Mario C. Delgado" "/tags/mario-c-delgado/">
|
65 |
#<Mechanize::Page::Link "Tom Dale" "/tags/tom-dale/">
|
66 |
#<Mechanize::Page::Link "Obie Fernandez" "/tags/obie-fernandez/">
|
67 |
#<Mechanize::Page::Link "Chad Pytel" "/tags/chad-pytel/">
|
68 |
#<Mechanize::Page::Link "Zach Holman" "/tags/zach-holman/">
|
69 |
#<Mechanize::Page::Link "Max Luster" "/tags/max-luster/">
|
70 |
#<Mechanize::Page::Link "Kyle Fiedler" "/tags/kyle-fiedler/">
|
71 |
#<Mechanize::Page::Link "Roberto Machado" "/tags/roberto-machado/">}
|
72 |
{forms}> |
Jika Anda ingin melihat halaman HTML itu sendiri, Anda dapat memberi tag pada metode body
atau content
.
some_scraper.rb
1 |
...
|
2 |
|
3 |
print page.body |
4 |
|
5 |
...
|
Keluaran
1 |
<!doctype html>
|
2 |
|
3 |
<html>
|
4 |
<head>
|
5 |
<meta charset="utf-8" /> |
6 |
<meta http-equiv='X-UA-Compatible' content='IE=edge;chrome=1' /> |
7 |
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> |
8 |
<meta name="viewport" content="initial-scale=1"> |
9 |
<title>Between | Screens </title> |
10 |
<link rel="alternate" type="application/atom+xml" title="Atom Feed" href="/feed.xml" /> |
11 |
<link href="stylesheets/all-11b45acc.css" rel="stylesheet" /> |
12 |
<script src="javascripts/all-4c20da82.js"></script> |
13 |
</head>
|
14 |
|
15 |
<body>
|
16 |
<header>
|
17 |
<div id="logo"> |
18 |
<a href="/"><img src="images/Between_Screens_Logo_Cube_Up-539d6997.svg" alt="Logo cube" /></a> |
19 |
</div>
|
20 |
<nav class="navigation"> |
21 |
<ul class="nav-list"> |
22 |
fork">https://github.com/vis-kid/betweenscreens">fork! |
23 |
<li><a href="pages/about/">about</a></li> |
24 |
<li><a href="design/">design</a></li> |
25 |
<li><a href="code/">code</a></li> |
26 |
</ul>
|
27 |
</nav>
|
28 |
</header>
|
29 |
|
30 |
<div id="main" role="main"> |
31 |
<div class='posts'> |
32 |
<ul>
|
33 |
<li>
|
34 |
<article class="index-article"> |
35 |
<span class='post-date'>Oct 27 | 2016</span><h2 class='post-title'><a href="episodes/144/">Randy J. Hunt</a></h2> |
36 |
<h3 class='topic-list'>Organizing teams | Diversity | Desires | Pizza rule | Effective over clever | Novel solutions | Straightforwardness | Research | Coffeeshop test | Small changes | Reducing errors | Granular diffs</h3> |
37 |
<div class='soundcloud-player-small'> |
38 |
<iframe width="100%" |
39 |
height="166" |
40 |
scrolling="no" |
41 |
frameborder="no" |
42 |
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/290328784&color=ff0000&...> |
43 |
</div>
|
44 |
</article>
|
45 |
</li>
|
46 |
|
47 |
<li>
|
48 |
<article class="index-article"> |
49 |
<span class='post-date'>Oct 25 | 2016</span><h2 class='post-title'><a href="episodes/143/">Jason Long</a></h2> |
50 |
<h3 class='topic-list'>Open source | Empathy | Lower barriers | Learning tool | Design contributions | Git website | Branding | GitHub | Neovim | Tmux | Design love | Knowing audiences | Showing work | Dribbble | Progressions | Ideas</h3> |
51 |
<div class='soundcloud-player-small'> |
52 |
<iframe width="100%" |
53 |
height="166" |
54 |
scrolling="no" |
55 |
frameborder="no" |
56 |
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/290126141&color=ff0000&...> |
57 |
</div>
|
58 |
</article>
|
59 |
</li>
|
60 |
|
61 |
<li>
|
62 |
<article class="index-article"> |
63 |
<span class='post-date'>Oct 18 | 2016</span><h2 class='post-title'><a href="episodes/142/">David Heinemeier Hansson</a></h2> |
64 |
<h3 class='topic-list'>Rails community | Tone | Technical disagreements | Community policing | Ungratefulness | No assholes allowed | Basecamp | Open source persona | Aspirations | Guarding motivations | Dealing with audiences | Pressure | Honesty | Diverse opinions | Small talk</h3> |
65 |
<div class='soundcloud-player-small'> |
66 |
<iframe width="100%" |
67 |
height="166" |
68 |
scrolling="no" |
69 |
frameborder="no" |
70 |
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/289018386&color=ff0000&...> |
71 |
</div>
|
72 |
</article>
|
73 |
</li>
|
74 |
|
75 |
<li>
|
76 |
<article class="index-article"> |
77 |
<span class='post-date'>Oct 12 | 2016</span><h2 class='post-title'><a href="episodes/141/">Zach Holman</a></h2> |
78 |
<h3 class='topic-list'>Getting Fired | Taboo | Transparency | Different Perspectives | Timing | Growth Stages | Employment & Dating | Managers | At-will Employment | Tech Industry | Europe | Low hanging Fruits | Performance Improvement Plans | Meeting Goals | Surprise Firings | Firing Fast | Mistakes | Company Culture | Communication</h3> |
79 |
<div class='soundcloud-player-small'> |
80 |
<iframe width="100%" |
81 |
height="166" |
82 |
scrolling="no" |
83 |
frameborder="no" |
84 |
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/287425105&color=ff0000&...> |
85 |
</div>
|
86 |
</article>
|
87 |
</li>
|
88 |
|
89 |
<li>
|
90 |
<article class="index-article"> |
91 |
<span class='post-date'>Oct 10 | 2016</span><h2 class='post-title'><a href="episodes/140/">Joel Glovier</a></h2> |
92 |
<h3 class='topic-list'>Digital Product Design | Product Design @ GitHub | Loving Design | Order & Chaos | Drawing | Web Design | HospitalRun | Diversity | Startup Culture | Improving Lives | CURE International | Ember | Offline First | Hospital Information System | Designers & Open Source</h3> |
93 |
<div class='soundcloud-player-small'> |
94 |
<iframe width="100%" |
95 |
height="166" |
96 |
scrolling="no" |
97 |
frameborder="no" |
98 |
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/287105342&color=ff0000&...> |
99 |
</div>
|
100 |
</article>
|
101 |
</li>
|
102 |
|
103 |
<li>
|
104 |
<article class="index-article"> |
105 |
<span class='post-date'>Aug 26 | 2015</span><h2 class='post-title'><a href="episodes/139/">João Ferreira</a></h2> |
106 |
<h3 class='topic-list'>Masters @ Work | Subvisual | Deadlines | Design personality | Design problems | Team | Pushing envelopes | Delightful experiences | Perfecting details | Company values</h3> |
107 |
<div class='soundcloud-player-small'> |
108 |
<iframe width="100%" |
109 |
height="166" |
110 |
scrolling="no" |
111 |
frameborder="no" |
112 |
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/221003494&color=ff0000&...> |
113 |
</div>
|
114 |
</article>
|
115 |
</li>
|
116 |
|
117 |
<li>
|
118 |
<article class="index-article"> |
119 |
<span class='post-date'>Aug 06 | 2015</span><h2 class='post-title'><a href="episodes/138/">Corwin Harrell</a></h2> |
120 |
<h3 class='topic-list'>Q&A | 01 | University | Graphic design | Design setup | Sublime | Atom | thoughtbot | Working location | Collaboration & pairing | Vim advocates | Daily routine | Standups | Clients | Coffee walks | Investment Fridays |</h3> |
121 |
<div class='soundcloud-player-small'> |
122 |
<iframe width="100%" |
123 |
height="166" |
124 |
scrolling="no" |
125 |
frameborder="no" |
126 |
src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/218101809&color=ff0000&...> |
127 |
</div>
|
128 |
</article>
|
129 |
</li>
|
130 |
</ul>
|
131 |
</div>
|
132 |
|
133 |
<section>
|
134 |
<div class='pagination-link'><a href="page/2/">Older Stuff »</a></div> |
135 |
</section>
|
136 |
</div>
|
137 |
|
138 |
<footer>
|
139 |
<div class='footer-tags'> |
140 |
<h3>Random Tags</h3> |
141 |
<ul class='random-tag-list'> |
142 |
<li><a href="/tags/exercise/">Exercise</a></li> |
143 |
<li><a href="/tags/company-benefits/">Company benefits</a></li> |
144 |
<li><a href="/tags/tmux/">Tmux</a></li> |
145 |
<li><a href="/tags/filetask/">FileTask</a></li> |
146 |
<li><a href="/tags/decision-making/">Decision making</a></li> |
147 |
<li><a href="/tags/favorite-feature/">Favorite feature</a></li> |
148 |
<li><a href="/tags/working-out/">Working out</a></li> |
149 |
<li><a href="/tags/scott-savarie/">Scott Savarie</a></li> |
150 |
<li><a href="/tags/titles/">Titles</a></li> |
151 |
<li><a href="/tags/erik-spiekermann/">Erik Spiekermann</a></li> |
152 |
<li><a href="/tags/newbie-mistakes/">Newbie mistakes</a></li> |
153 |
<li><a href="/tags/playbook/">Playbook</a></li> |
154 |
<li><a href="/tags/delegation/">Delegation</a></li> |
155 |
<li><a href="/tags/heat-maps/">Heat maps</a></li> |
156 |
<li><a href="/tags/europe/">Europe</a></li> |
157 |
<li><a href="/tags/sizing-type/">Sizing type</a></li> |
158 |
<li><a href="/tags/focus/">Focus</a></li> |
159 |
<li><a href="/tags/virtual-assistants/">Virtual assistants</a></li> |
160 |
<li><a href="/tags/writing/">Writing</a></li> |
161 |
<li><a href="/tags/hacking/">Hacking</a></li> |
162 |
</ul>
|
163 |
</div>
|
164 |
|
165 |
<div class='recent-posts'> |
166 |
<h3>Random Interviewees</h3> |
167 |
<ul>
|
168 |
<li><a href="/tags/joel-glovier/">Joel Glovier</a></li> |
169 |
<li><a href="/tags/corwin-harrell/">Corwin Harrell</a></li> |
170 |
<li><a href="/tags/mario-c-delgado/">Mario C. Delgado</a></li> |
171 |
<li><a href="/tags/tom-dale/">Tom Dale</a></li> |
172 |
<li><a href="/tags/obie-fernandez/">Obie Fernandez</a></li> |
173 |
<li><a href="/tags/chad-pytel/">Chad Pytel</a></li> |
174 |
<li><a href="/tags/zach-holman/">Zach Holman</a></li> |
175 |
<li><a href="/tags/max-luster/">Max Luster</a></li> |
176 |
<li><a href="/tags/kyle-fiedler/">Kyle Fiedler</a></li> |
177 |
<li><a href="/tags/roberto-machado/">Roberto Machado</a></li> |
178 |
</ul>
|
179 |
</div>
|
180 |
</footer>
|
181 |
</body>
|
182 |
</html>
|
Karena podcast ini hanya memiliki sejumlah kecil elemen yang berbeda pada halaman, inilah Mechanize::Page
yang akan dikembalikan dari github.com. Ini memiliki variasi konten yang lebih besar untuk dilihat. Saya pikir ini penting untuk Anda rasakan.
Keluaran github.com
1 |
#<Mechanize::Page
|
2 |
{url #https://github.com/>} |
3 |
{meta_refresh} |
4 |
{title "How people build software · GitHub"} |
5 |
{iframes} |
6 |
{frames} |
7 |
{links
|
8 |
#<Mechanize::Page::Link "Skip to content" "#start-of-content">
|
9 |
#https://github.com/">
|
10 |
#<Mechanize::Page::Link "\n Personal\n" "/personal">
|
11 |
#<Mechanize::Page::Link "\n Open source\n" "/open-source">
|
12 |
#<Mechanize::Page::Link "\n Business\n" "/business">
|
13 |
#<Mechanize::Page::Link "\n Explore\n" "/explore">
|
14 |
#<Mechanize::Page::Link "Sign up" "/join?source=header-home">
|
15 |
#<Mechanize::Page::Link "Sign in" "/login">
|
16 |
#<Mechanize::Page::Link "Pricing" "/pricing">
|
17 |
#<Mechanize::Page::Link "Blog" "/blog">
|
18 |
#https://help.github.com">
|
19 |
#https://github.com/search">
|
20 |
#https://help.github.com/terms">
|
21 |
#https://help.github.com/privacy">
|
22 |
#<Mechanize::Page::Link "Sign up for GitHub" "/join?source=button-home">
|
23 |
#<Mechanize::Page::Link
|
24 |
"\n \n \n \n \n A whole new Universe\n \n Learn about the exciting features and announcements revealed at this year's GitHub Universe conference.\n \n \n " |
25 |
"/universe-2016"> |
26 |
#<Mechanize::Page::Link "Individuals " "/personal">
|
27 |
#<Mechanize::Page::Link "Communities " "/open-source">
|
28 |
#<Mechanize::Page::Link "Businesses " "/business">
|
29 |
#<Mechanize::Page::Link "NASA" "//github.com/nasa">
|
30 |
#<Mechanize::Page::Link "Sign up for GitHub" "/join?source=button-home">
|
31 |
#https://github.com/contact">
|
32 |
#https://developer.github.com">
|
33 |
#https://training.github.com">
|
34 |
#https://shop.github.com">
|
35 |
#https://github.com/blog">
|
36 |
#https://github.com/about">
|
37 |
#https://github.com">
|
38 |
#https://github.com/site/terms">
|
39 |
#https://github.com/site/privacy">
|
40 |
#https://github.com/security">
|
41 |
#https://status.github.com/">
|
42 |
#https://help.github.com">
|
43 |
#<Mechanize::Page::Link "Reload" "">
|
44 |
#<Mechanize::Page::Link "Reload" "">}
|
45 |
{forms
|
46 |
#<Mechanize::Form
|
47 |
{name nil} |
48 |
{method "GET"} |
49 |
{action "/search"} |
50 |
{fields
|
51 |
[hidden:0x3feb90f8297c type: hidden name: utf8 value: ✓] |
52 |
[text:0x3feb90f827d8 type: text name: q value: ]} |
53 |
{radiobuttons} |
54 |
{checkboxes} |
55 |
{file_uploads} |
56 |
{buttons}> |
57 |
#<Mechanize::Form
|
58 |
{name nil} |
59 |
{method "POST"} |
60 |
{action "/join"} |
61 |
{fields
|
62 |
[hidden:0x3feb90f7be38 type: hidden name: utf8 value: ✓] |
63 |
[hidden:0x3feb90f7bbb8 type: hidden name: authenticity_token value: vjRATKj7smXreq6Lt02r+MzW+ewWoi+fRzQXPedFAlOZgwzxQ0dZnChirhDfd7vyWZZZBO+ZFydLNedjIEDsrQ==] |
64 |
[text:0x3feb90f7b9d8 type: text name: user[login] value: ] |
65 |
[text:0x3feb90f7b7f8 type: text name: user[email] value: ] |
66 |
[field:0x3feb90f7b654 type: password name: user[password] value: ] |
67 |
[hidden:0x3feb90f7b474 type: hidden name: source value: form-home]} |
68 |
{radiobuttons} |
69 |
{checkboxes} |
70 |
{file_uploads} |
71 |
{buttons [button:0x3feb90f7a038 type: submit name: value: ]}>}> |
Kembali ke podcast, Anda juga dapat melihat hal-hal seperti pengkodean, kode tanggapan HTTP, URI, atau header tanggapan.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
puts 'Encodings' |
10 |
puts page.encodings |
11 |
puts 'Repsonse Headers' |
12 |
puts page.response |
13 |
puts 'HTTP response code' |
14 |
puts page.code |
15 |
puts 'URI' |
16 |
puts page.uri |
Keluaran
1 |
Encodings |
2 |
EUC-JP |
3 |
utf-8 |
4 |
utf-8 |
5 |
|
6 |
Repsonse Headers |
7 |
{"server"=>"GitHub.com", "date"=>"Sat, 29 Oct 2016 17:56:00 GMT", "content-type"=>"text/html; charset=utf-8", "transfer-encoding"=>"chunked", "last-modified"=>"Fri, 28 Oct 2016 01:48:56 GMT", "access-control-allow-origin"=>"*", "expires"=>"Sat, 29 Oct 2016 18:06:00 GMT", "cache-control"=>"max-age=600", "content-encoding"=>"gzip", "x-github-request-id"=>"501C936D:C723:1631523C:5814E2B0"} |
8 |
|
9 |
HTTP response code |
10 |
200 |
11 |
|
12 |
URI |
13 |
http://betweenscreens.fm/ |
Ada banyak hal lagi jika Anda ingin menggali lebih dalam. Akan saya tinggalkan seperti itu.
Metode Nokogiri
at
search
Mechanize menggunakan Nokogiri untuk meng-scrape data dari halaman. Anda bisa menerapkan apa yang Anda pelajari tentang Nokogiri di artikel pertama dan menggunakannya di halaman Mechanize juga. Itu berarti Anda umumnya menggunakan Mechanize untuk menavigasi halaman dan metode Nokogiri untuk kebutuhan scrape Anda.
Misalnya, jika Anda ingin mencari satu objek, Anda bisa menggunakan at
, sementara search
mengembalikan semua objek yang sesuai dengan pemilih pada halaman tertentu. Untuk mengulanginya, metode-metode ini akan bekerja baik pada dokumen Nokogiri dan objek halaman Mechanize.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
first_title = page.at('h2.post-title') |
10 |
|
11 |
all_titles = page.search('h2.post-title') |
12 |
|
13 |
all_titles.each do |title| |
14 |
puts title |
15 |
end
|
16 |
|
17 |
puts " * "*33 |
18 |
|
19 |
puts first_title |
Keluaran
1 |
<h2 class="post-title"><a href="episodes/144/">Randy J. Hunt</a></h2> |
2 |
<h2 class="post-title"><a href="episodes/143/">Jason Long</a></h2> |
3 |
<h2 class="post-title"><a href="episodes/142/">David Heinemeier Hansson</a></h2> |
4 |
<h2 class="post-title"><a href="episodes/141/">Zach Holman</a></h2> |
5 |
<h2 class="post-title"><a href="episodes/140/">Joel Glovier</a></h2> |
6 |
<h2 class="post-title"><a href="episodes/139/">João Ferreira</a></h2> |
7 |
<h2 class="post-title"><a href="episodes/138/">Corwin Harrell</a></h2> |
8 |
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
9 |
<h2 class="post-title"><a href="episodes/144/">Randy J. Hunt</a></h2> |
Tautan-tautan
links
link_with
links_with
Kita juga bisa menavigasi seluruh situs sesuai dengan keinginan kita. Mungkin bagian terpenting dari Mechanize adalah kemampuannya untuk membiarkan Anda bermain dengan tautan. Jika tidak, Anda bisa tetap bertahan dengan Nokogiri itu sendiri. Mari kita lihat apa yang kita dapatkan kembali jika kita meminta halaman untuk tautannya.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
puts "#{page.links}" |
Keluaran
1 |
[#<Mechanize::Page::Link "Logo cube" "/"> |
2 |
, #https://github.com/vis-kid/betweenscreens">
|
3 |
, #<Mechanize::Page::Link "about" "pages/about/">
|
4 |
, #<Mechanize::Page::Link "design" "design/">
|
5 |
, #<Mechanize::Page::Link "code" "code/">
|
6 |
, #<Mechanize::Page::Link "Randy J. Hunt" "episodes/144/">
|
7 |
, #<Mechanize::Page::Link "Jason Long" "episodes/143/">
|
8 |
, #<Mechanize::Page::Link "David Heinemeier Hansson" "episodes/142/">
|
9 |
, #<Mechanize::Page::Link "Zach Holman" "episodes/141/">
|
10 |
, #<Mechanize::Page::Link "Joel Glovier" "episodes/140/">
|
11 |
, #<Mechanize::Page::Link "João Ferreira" "episodes/139/">
|
12 |
, #<Mechanize::Page::Link "Corwin Harrell" "episodes/138/">
|
13 |
, #<Mechanize::Page::Link "Older Stuff »" "page/2/">
|
14 |
, #<Mechanize::Page::Link "Exercise" "/tags/exercise/">
|
15 |
, #<Mechanize::Page::Link "Company benefits" "/tags/company-benefits/">
|
16 |
, #<Mechanize::Page::Link "Tmux" "/tags/tmux/">
|
17 |
, #<Mechanize::Page::Link "FileTask" "/tags/filetask/">
|
18 |
, #<Mechanize::Page::Link "Decision making" "/tags/decision-making/">
|
19 |
, #<Mechanize::Page::Link "Favorite feature" "/tags/favorite-feature/">
|
20 |
, #<Mechanize::Page::Link "Working out" "/tags/working-out/">
|
21 |
, #<Mechanize::Page::Link "Scott Savarie" "/tags/scott-savarie/">
|
22 |
, #<Mechanize::Page::Link "Titles" "/tags/titles/">
|
23 |
, #<Mechanize::Page::Link "Erik Spiekermann" "/tags/erik-spiekermann/">
|
24 |
, #<Mechanize::Page::Link "Newbie mistakes" "/tags/newbie-mistakes/">
|
25 |
, #<Mechanize::Page::Link "Playbook" "/tags/playbook/">
|
26 |
, #<Mechanize::Page::Link "Delegation" "/tags/delegation/">
|
27 |
, #<Mechanize::Page::Link "Heat maps" "/tags/heat-maps/">
|
28 |
, #<Mechanize::Page::Link "Europe" "/tags/europe/">
|
29 |
, #<Mechanize::Page::Link "Sizing type" "/tags/sizing-type/">
|
30 |
, #<Mechanize::Page::Link "Focus" "/tags/focus/">
|
31 |
, #<Mechanize::Page::Link "Virtual assistants" "/tags/virtual-assistants/">
|
32 |
, #<Mechanize::Page::Link "Writing" "/tags/writing/">
|
33 |
, #<Mechanize::Page::Link "Hacking" "/tags/hacking/">
|
34 |
, #<Mechanize::Page::Link "Joel Glovier" "/tags/joel-glovier/">
|
35 |
, #<Mechanize::Page::Link "Corwin Harrell" "/tags/corwin-harrell/">
|
36 |
, #<Mechanize::Page::Link "Mario C. Delgado" "/tags/mario-c-delgado/">
|
37 |
, #<Mechanize::Page::Link "Tom Dale" "/tags/tom-dale/">
|
38 |
, #<Mechanize::Page::Link "Obie Fernandez" "/tags/obie-fernandez/">
|
39 |
, #<Mechanize::Page::Link "Chad Pytel" "/tags/chad-pytel/">
|
40 |
, #<Mechanize::Page::Link "Zach Holman" "/tags/zach-holman/">
|
41 |
, #<Mechanize::Page::Link "Max Luster" "/tags/max-luster/">
|
42 |
, #<Mechanize::Page::Link "Kyle Fiedler" "/tags/kyle-fiedler/">
|
43 |
, #<Mechanize::Page::Link "Roberto Machado" "/tags/roberto-machado/">
|
44 |
]
|
Holy moly, mari kita rinci ini. Karena kita belum memberi tahu Mechanize untuk mencari tempat lain, kita mendapat banyak tautan dari hanya halaman pertama tersebut. Mechanize pergi melewati halaman itu dalam urutan menurun dan mengembalikan daftar tautan ini dari atas ke bawah. Saya telah membuat gambar kecil dengan pointer hijau ke berbagai tautan yang dapat Anda lihat di keluaran.
Omong-omong, ini sudah menunjukkan hasil akhir dari desain ulang untuk podcast saya. Saya pikir versi ini sedikit lebih baik untuk tujuan demonstrasi. Anda juga bisa melihat sekilas bagaimana hasil akhirnya terlihat dan mengapa saya perlu meng-scrape situs Sinatra lama saya.
Tangkapan Layar



Seperti biasa, kita juga bisa mengekstrak teks saja darinya.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
page.links.each do |link| |
10 |
puts link.text |
11 |
end
|
Keluaran
1 |
Logo cube |
2 |
fork! |
3 |
about |
4 |
design |
5 |
code |
6 |
Randy J. Hunt |
7 |
Jason Long |
8 |
David Heinemeier Hansson |
9 |
Zach Holman |
10 |
Joel Glovier |
11 |
João Ferreira |
12 |
Corwin Harrell |
13 |
Older Stuff » |
14 |
Exercise |
15 |
Company benefits |
16 |
Tmux |
17 |
FileTask |
18 |
Decision making |
19 |
Favorite feature |
20 |
Working out |
21 |
Scott Savarie |
22 |
Titles |
23 |
Erik Spiekermann |
24 |
Newbie mistakes |
25 |
Playbook |
26 |
Delegation |
27 |
Heat maps |
28 |
Europe |
29 |
Sizing type
|
30 |
Focus |
31 |
Virtual assistants |
32 |
Writing |
33 |
Hacking |
34 |
Joel Glovier |
35 |
Corwin Harrell |
36 |
Mario C. Delgado |
37 |
Tom Dale |
38 |
Obie Fernandez |
39 |
Chad Pytel |
40 |
Zach Holman |
41 |
Max Luster |
42 |
Kyle Fiedler |
43 |
Roberto Machado |
Mendapatkan semua tautan ini dalam jumlah besar bisa sangat berguna atau hanya membosankan. Beruntung bagi kita, kita memiliki beberapa alat untuk menyesuaikan apa yang kita butuhkan.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
focus_link = agent.page.links.find { |link| link.text == 'Focus' } |
10 |
|
11 |
puts focus_link |
Keluaran
1 |
Focus |
Boom! Sekarang kita mempunyai tujuan! Kita bisa memperbesar tautan tertentu seperti itu. Kita dapat menargetkan tautan yang sesuai dengan kriteria tertentu—seperti teksnya, misalnya—dengan API yang lebih bagus seperti links_with
atau link_with
. Selain itu, jika ada beberapa tautan Focus
, kita dapat memperbesar sejumlah tertentu di halaman yang menggunakan tanda kurung []
.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
focus_link = agent.page.links_with(:text => 'Focus')[2] |
10 |
|
11 |
puts focus_link |
Jika Anda tidak mencari teks tautan tapi tautan itu sendiri, Anda hanya perlu menentukan href
tertentu untuk menemukan tautannya. Mechanize tidak akan menghalangi Anda. Alih-alih text
, Anda memberi feed metodenya dengan href
.
some_scraper.rb
1 |
page = agent.page.link_with(href: '/episodes/95/') |
2 |
|
3 |
page = agent.page.links_with(href: '/episodes/95/') |
Jika Anda hanya ingin mencari tautan pertama dengan teks yang diinginkan, Anda juga bisa menggunakan sintaks ini. Sangat mudah dan sedikit lebih mudah dibaca.
some_scraper.rb
1 |
focus_links = agent.page.link_with(:text => 'Focus') |
Bagaimana dengan mengikuti teman tersebut dan melihat apa yang tersembunyi di balik tautan Focus
ini? Mari kita klik
!
Klik
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
focus_links = agent.page.links.find { |link| link.text == 'Focus' }.click.links |
10 |
|
11 |
puts focus_links |
Ini akan membuat daftar panjang lainnya seperti sebelumnya. Lihat betapa mudahnya menggabungkan .click.links
. Mechanize mengklik tautan untuk Anda dan mengikuti halaman ke tujuan yang baru. Karena kita juga meminta daftar tautan, kita akan mendapatkan semua tautan yang dapat ditemukan Mechanize di halaman baru tersebut.
Katakanlah saya memiliki dua tautan teks dari yang diwawancarai yang sama—yang mentautkan ke tag dan satu dengan episode terakhir—dan saya ingin mendapatkan tautan dari masing-masing halaman ini.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
podcast_url = "http://betweenscreens.fm/" |
6 |
|
7 |
page = agent.get(podcast_url) |
8 |
|
9 |
links = agent.page.links_with(text: "Some interviewee") |
10 |
|
11 |
links.each do |link| |
12 |
puts link.click.links |
13 |
end
|
Ini akan memberi Anda daftar tautan untuk kedua halaman. Anda mengulangi setiap tautan untuk yang diwawancarai, dan Mechanize mengikuti tautan yang diklik dan mengumpulkan tautan yang ditemukannya di halaman baru untuk Anda. Di bawah ini Anda dapat menemukan beberapa contoh di mana Anda dapat membandingkan kombinasi untuk Anda memulai.
some_scraper.rb
1 |
agent.page.links.find { |l| l.text == 'Focus' } |
2 |
agent.page.links.find { |l| l.text == 'Focus' }.click |
3 |
agent.page.link_with(text: 'Focus') |
4 |
agent.page.links_with(text: 'Focus')[0] |
5 |
agent.page.links_with(text: 'Focus')[1].click |
6 |
agent.page.links_with(text: 'Focus')[2].click.links |
7 |
agent.page.link_with(href: '/some-href') |
8 |
agent.page.link_with(href: '/some-href').click |
9 |
agent.page.links_with(href: '/some-href') |
10 |
agent.page.links_with(href: '/some-href').click |
Formulir
submit
field_with
checkbox_with
radiobuttons_with
file_uploads
Mari kita lihat formulirnya!
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
google_url = "http://google.com/" |
6 |
|
7 |
page = agent.get(google_url) |
8 |
|
9 |
forms = page.forms |
10 |
|
11 |
puts forms.inspect |
Keluaran
1 |
[#<Mechanize::Form |
2 |
# Attention!!
|
3 |
{name "f"} |
4 |
# Attention!!
|
5 |
{method "GET"} |
6 |
{action "/search"} |
7 |
{fields
|
8 |
[hidden:0x3fea91d2eb08 type: hidden name: ie value: ISO-8859-1] |
9 |
[hidden:0x3fea91d2e964 type: hidden name: hl value: es] |
10 |
[hidden:0x3fea91d2e7e8 type: hidden name: source value: hp] |
11 |
[hidden:0x3fea91d2e5f4 type: hidden name: biw value: ] |
12 |
[hidden:0x3fea91d2e428 type: hidden name: bih value: ] |
13 |
# Attention!!
|
14 |
[text:0x3fea91d2e248 type: name: q value: ] |
15 |
# Attention!!
|
16 |
[hidden:0x3fea91d2bcb4 type: hidden name: gbv value: 1]} |
17 |
{radiobuttons} |
18 |
{checkboxes} |
19 |
{file_uploads} |
20 |
{buttons
|
21 |
[submit:0x3fea91d2e0f4 type: submit name: btnG value: Buscar con Google] |
22 |
[submit:0x3fea91d2be80 type: submit name: btnI value: Voy a tener suerte]}> |
23 |
]
|
Karena kita menggunakan metode forms
, kita mendapatkan sebuah array yang dikembalikan—bahkan ketika kita hanya memiliki satu formulir yang dikembalikan kepada kita. Sekarang kita tahu bahwa formulirnya memiliki nama "f"
, kita bisa menggunakan form
versi tunggal untuk mengasahnya.
1 |
... |
2 |
|
3 |
{name "f"} |
4 |
|
5 |
... |
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
google_url = "http://google.com/" |
6 |
|
7 |
page = agent.get(google_url) |
8 |
|
9 |
search_form = page.form('f') |
10 |
|
11 |
puts search_form.inspect |
Dengan menggunakan form('f')
, kita memilih formulir khusus yang ingin kita bekerja dengannya. Akibatnya, kita tidak akan mendapatkan array yang dikembalikan.
Keluaran
1 |
#<Mechanize::Form
|
2 |
# Attention!!
|
3 |
{name "f"} |
4 |
# Attention!!
|
5 |
{method "GET"} |
6 |
{action "/search"} |
7 |
{fields
|
8 |
[hidden:0x3ffe9ce85ba4 type: hidden name: ie value: ISO-8859-1] |
9 |
[hidden:0x3ffe9ce859d8 type: hidden name: hl value: es] |
10 |
[hidden:0x3ffe9ce857bc type: hidden name: source value: hp] |
11 |
[hidden:0x3ffe9ce85618 type: hidden name: biw value: ] |
12 |
[hidden:0x3ffe9ce853e8 type: hidden name: bih value: ] |
13 |
# Attention!!
|
14 |
[text:0x3ffe9ce851cc type: name: q value: ] |
15 |
# Attention!!
|
16 |
[hidden:0x3ffe9ce84bdc type: hidden name: gbv value: 1]} |
17 |
{radiobuttons} |
18 |
{checkboxes} |
19 |
{file_uploads} |
20 |
{buttons
|
21 |
[submit:0x3ffe9ce85078 type: submit name: btnG value: Buscar con Google] |
22 |
[submit:0x3ffe9ce84e48 type: submit name: btnI value: Voy a tener suerte]}> |
Kita juga bisa mengidentifikasi nama field masukan teks (q
).
1 |
... |
2 |
|
3 |
[text:0x3ffe9ce851cc type: name: q value: ] |
4 |
|
5 |
... |
Kita bisa mentargetnya dengan nama itu dan tetapkan nilainya seperti atribut Ruby. Yang perlu kita lakukan adalah memberikannya dengan nilai baru. Anda dapat melihat dari contoh keluaran di atas yang kosong secara default.
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
google_url = "http://google.com/" |
6 |
|
7 |
page = agent.get(google_url) |
8 |
|
9 |
search_form = page.form('f') |
10 |
search_form.q = 'New Google Search' |
11 |
|
12 |
puts search_form.inspect |
Keluaran
1 |
#<Mechanize::Form
|
2 |
{name "f"} |
3 |
{method "GET"} |
4 |
{action "/search"} |
5 |
{fields
|
6 |
[hidden:0x3fcb85b6a784 type: hidden name: ie value: ISO-8859-1] |
7 |
[hidden:0x3fcb85b6a57c type: hidden name: hl value: es] |
8 |
[hidden:0x3fcb85b6a3b0 type: hidden name: source value: hp] |
9 |
[hidden:0x3fcb85b6a16c type: hidden name: biw value: ] |
10 |
[hidden:0x3fcb85b67f20 type: hidden name: bih value: ] |
11 |
# Attention!!
|
12 |
[text:0x3fcb85b67d18 type: name: q value: New Google Search] |
13 |
# Attention!!
|
14 |
[hidden:0x3fcb85b67728 type: hidden name: gbv value: 1]} |
15 |
{radiobuttons} |
16 |
{checkboxes} |
17 |
{file_uploads} |
18 |
{buttons
|
19 |
[submit:0x3fcb85b67b9c type: submit name: btnG value: Buscar con Google] |
20 |
[submit:0x3fcb85b67994 type: submit name: btnI value: Voy a tener suerte]}> |
Seperti yang dapat Anda amati di atas, nilai field teks telah berubah ke New Google Search
. Sekarang kita hanya perlu submit
formulir dan mengumpulkan hasilnya dari halaman yang dikembalikan Google. Tidak bisa yang lebih mudah. Mari kita cari yang lain kali ini!
some_scraper.rb
1 |
require 'mechanize' |
2 |
|
3 |
agent = Mechanize.new |
4 |
|
5 |
google_url = "http://google.com/" |
6 |
page = agent.get(google_url) |
7 |
|
8 |
search_form = page.form('f') |
9 |
search_form.q = 'GitHub TouchFart' |
10 |
|
11 |
page = agent.submit(search_form) |
12 |
|
13 |
pp page.search('h3.r').map(&:text) |
Di sini saya mengidentifikasi header hasil pencarian menggunakan penyeleksi CSS h3.r,
memetakan text
-nya, dan mencetak hasilnya dengan cantik. Tidak sesulit itu, bukan? Itu adalah contoh yang mudah, tentu, tapi pikirkan kemungkinan tak terbatas yang Anda miliki dengan ini!
Keluaran
1 |
["GitHub - hungtruong/TouchFart: A fart app for the new Macbook ...", |
2 |
"TouchFart/TouchFart at master · hungtruong/TouchFart · GitHub",
|
3 |
"Commits · hungtruong/TouchFart · GitHub",
|
4 |
"Projects · hungtruong/TouchFart · GitHub",
|
5 |
"Pull Requests · hungtruong/TouchFart · GitHub",
|
6 |
"Issues · hungtruong/TouchFart · GitHub",
|
7 |
"TouchFart/license.txt at master · hungtruong/TouchFart · GitHub",
|
8 |
"Add autoplay attribute to <audio> tag and touchfart (er ... - GitHub",
|
9 |
"Find file - File Finder · GitHub",
|
10 |
"Fart app for the new Macbook Pro's Touch... #3860 on topic touchfart ..."] |
Mechanize memiliki bidang masukan yang berbeda yang tersedia untuk Anda mainkan. Anda bahkan bisa mengunggah file!
field_with
checkbox_with
radiobuttons_with
file_uploads
Anda juga bisa mengenali tombol radio dan kotak centang dengan nama mereka dan mencentangnya—Anda bisa menebaknya—check
.
some_scraper.rb
1 |
form.radiobuttons_with(:name => 'gender')[3].check |
2 |
|
3 |
form.checkbox_with(:name => 'coder').check |
Tag option menawarkan pengguna untuk memilih satu item dari daftar drop-down. Sekali lagi, kita targetkan mereka dengan nama dan memilih nomor pilihan yang kita inginkan.
some_scraper.rb
1 |
form.field_with(:name => 'countries').options[22].select |
Pengunggahan file bekerja sama dengan memasukkan teks ke dalam formulir dengan menyetelnya seperti atribut-atribut Ruby. Anda mengidentifikasi kolom unggahan dan kemudian menentukan path file (nama file) yang ingin Anda transfer. Kedengarannya lebih rumit dari itu. Mari kita lihat!
some_scraper.rb
1 |
form.file_uploads.first.file_name = "some-path/some-image.jpg" |
Pemikiran Akhir
Lihat, tidak ada keajaiban! Anda sekarang dilengkapi dengan baik untuk bersenang-senang sendiri. Tentu ada sedikit lebih banyak untuk belajar tentang Nokogiri dan Mechanize, tapi bukannya menghabiskan terlalu banyak waktu untuk aspek yang tidak perlu, bermain-main dengannya dan melihat beberapa dokumentasi lagi saat Anda mengalami masalah di luar lingkup artikel pemula.
Saya harap Anda bisa melihat betapa indahnya gem ini dan berapa banyak kekuatan yang ditawarkannya. Seperti yang kita semua tahu dari budaya populer sekarang, ini juga memikul tanggung jawab. Gunakan di dalam kerangka hukum dan bila Anda tidak memiliki akses ke API. Anda mungkin tidak akan sering menggunakan alat ini, tapi sungguh mereka berguna saat Anda memiliki beberapa kebutuhan scraping nyata di depan Anda.
Seperti yang dijanjikan, pada artikel selanjutnya kita akan membahas contoh dunia nyata dimana saya akan meng-scrape data dari situs podcast saya. Saya akan mengekstraknya dari situs Sinatra yang lama dan memindahkannya ke situs Middleman baru saya yang menggunakan file .markdown
untuk setiap episode. Kita akan mengekstrak tanggal, nomor episode, nama yang diwawancarai, header, subheader, dan sebagainya. Sampai jumpa!