本篇文章抓取目标网站的链接的基础上,进一步提高难度,抓取目标页面上我们所需要的内容并保存在数据库中。这里的测试案例选用了一个我常用的电影下载网站(http://www.80s.la/)。本来是想抓取网站上的所有电影的下载链接,后来感觉需要的时间太长,因此改成了抓取2015年电影的下载链接。
一 原理简介
其实原理都跟第一篇文章差不多,不同的是鉴于这个网站的分类列表实在太多,如果不对这些标签加以取舍的话,需要花费的时间难以想象。
分类链接和标签链接都不要,不通过这些链接去爬取其他页面,只通过页底的所有类型电影的分页去获取其他页面的电影列表即可。同时,对于电影详情页面,仅仅只是抓取其中的电影标题和迅雷下载链接,并不进行深层次的爬行,详情页面的一些推荐电影等链接通通不要。
最后就是将所有获取到的电影的下载链接保存在videoLinkMap这个集合中,通过遍历这个集合将数据保存到MySQL里
二 代码实现
实现原理已经在上面说了,并且代码中有详细注释,因此这里就不多说了,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
package action;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class VideoLinkGrab {
public static void main(String[] args) {
VideoLinkGrab videoLinkGrab = new VideoLinkGrab();
videoLinkGrab.saveData( "http://www.80s.la/movie/list/-2015----p" );
}
/**
* 将获取到的数据保存在数据库中
*
* @param baseUrl
* 爬虫起点
* @return null
* */
public void saveData(String baseUrl) {
Map<String, Boolean> oldMap = new LinkedHashMap<String, Boolean>(); // 存储链接-是否被遍历
Map<String, String> videoLinkMap = new LinkedHashMap<String, String>(); // 视频下载链接
String oldLinkHost = "" ; // host
Pattern p = Pattern.compile( "(https?://)?[^/\\s]*" ); // 比如:http://www.zifangsky.cn
Matcher m = p.matcher(baseUrl);
if (m.find()) {
oldLinkHost = m.group();
}
oldMap.put(baseUrl, false );
videoLinkMap = crawlLinks(oldLinkHost, oldMap);
// 遍历,然后将数据保存在数据库中
try {
Connection connection = JDBCDemo.getConnection();
for (Map.Entry<String, String> mapping : videoLinkMap.entrySet()) {
PreparedStatement pStatement = connection
.prepareStatement( "insert into movie(MovieName,MovieLink) values(?,?)" );
pStatement.setString( 1 , mapping.getKey());
pStatement.setString( 2 , mapping.getValue());
pStatement.executeUpdate();
pStatement.close();
// System.out.println(mapping.getKey() + " : " + mapping.getValue());
}
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 抓取一个网站所有可以抓取的网页链接,在思路上使用了广度优先算法 对未遍历过的新链接不断发起GET请求, 一直到遍历完整个集合都没能发现新的链接
* 则表示不能发现新的链接了,任务结束
*
* 对一个链接发起请求时,对该网页用正则查找我们所需要的视频链接,找到后存入集合videoLinkMap
*
* @param oldLinkHost
* 域名,如:http://www.zifangsky.cn
* @param oldMap
* 待遍历的链接集合
*
* @return 返回所有抓取到的视频下载链接集合
* */
private Map<String, String> crawlLinks(String oldLinkHost,
Map<String, Boolean> oldMap) {
Map<String, Boolean> newMap = new LinkedHashMap<String, Boolean>(); // 每次循环获取到的新链接
Map<String, String> videoLinkMap = new LinkedHashMap<String, String>(); // 视频下载链接
String oldLink = "" ;
for (Map.Entry<String, Boolean> mapping : oldMap.entrySet()) {
// System.out.println("link:" + mapping.getKey() + "--------check:"
// + mapping.getValue());
// 如果没有被遍历过
if (!mapping.getValue()) {
oldLink = mapping.getKey();
// 发起GET请求
try {
URL url = new URL(oldLink);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setRequestMethod( "GET" );
connection.setConnectTimeout( 2500 );
connection.setReadTimeout( 2500 );
if (connection.getResponseCode() == 200 ) {
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream, "UTF-8" ));
String line = "" ;
Pattern pattern = null ;
Matcher matcher = null ;
//电影详情页面,取出其中的视频下载链接,不继续深入抓取其他页面
if (isMoviePage(oldLink)){
boolean checkTitle = false ;
String id="codetool">
注:如果想要实现抓取其他网站的一些指定内容的话,需要将其中的一些正则表达式根据实际情况进行合理修改 三 测试效果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。 延伸 · 阅读
精彩推荐
|