抓取网页数据工具(几个自己研究出来的抓数据的技术,欢迎大家指正补充哈哈!)
优采云 发布时间: 2022-01-18 18:11抓取网页数据工具(几个自己研究出来的抓数据的技术,欢迎大家指正补充哈哈!)
数据采集方面也有一点研究,现在分享一些自己研究过的数据采集技术。可能有很多缺点。欢迎指正和补充哈哈!
方法一:直接抓取网页源代码
优点:速度快。
缺点: 1、由于速度快,容易被服务器检测到,可能会限制当前ip的捕获。对此,可以尝试使用ip代码来解决。
2、如果要爬取的数据是网页加载后,js修改网页元素,无法爬取。
3、在抓取一些大的网站时,如果需要登录后抓取页面,可能需要破解服务器端账号加密算法和各种加密算法,是技术上的考验。
适用场景:网页是完全静态的,网页第一次加载后才加载要抓取的数据。类似的涉及登录或权限操作的页面不做任何账户加密或只做简单加密。
当然,如果你在网页上抓取的数据是通过接口获取的json,那你会更开心,直接抓取json页面就好了。
对于一个有登录的页面,我们如何在他的登录页面之后获取源代码?
首先,我想介绍一下,在会话中保存账户信息时,服务器是如何确定用户身份的。
首先,用户登录成功后,服务器会将用户当前的会话信息保存在会话中,每个会话都有唯一的标识sessionId。然后用户访问这个页面,会话创建完成后,会收到服务器返回的sessionId,并保存在cookie中。因此,我们可以使用chrome浏览器打开check项,查看当前页面的jsessionId。用户下次访问需要登录的页面时,会在用户发送的请求头中附加sessionId,服务器端可以通过这个sessionId判断用户的身份。
这里我搭建了一个简单的jsp登录页面,登录后的账号信息保存在服务器端的session中。
思路:1、登录。 2、登录成功后,会得到一个cookie。3. 将cookie放入请求头中,向登录页面发送请求。
附上java版和python的代码
爪哇版:
package craw;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
public class CrawTest {
//获得网页源代码
private static String getHtml(String urlString,String charset,String cookie){
StringBuffer html = new StringBuffer();
try {
URL url = new URL(urlString);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
urlConn.setRequestProperty("Cookie", cookie);
BufferedReader br = new BufferedReader(new InputStreamReader(urlConn.getInputStream(),charset));
String str;
while((str=br.readLine())!=null){
html.append(str);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return html.toString();
}
//发送post请求,并返回请求后的cookie
private static String postGetCookie(String urlString,String params,String charset){
String cookies=null;
try {
URL url = new URL(urlString);
URLConnection urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
PrintWriter out = new PrintWriter(urlConn.getOutputStream());
out.print(params);
out.flush();
cookies = urlConn.getHeaderFields().get("Set-Cookie").get(0);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return cookies;
}
public static void main(String[] args) {
String cookie = postGetCookie("http://localhost:8080/loginDemo/login",
"username=admin&password=123456","utf-8");
String html = getHtml("http://localhost:8080/loginDemo/index.jsp", "utf-8", cookie);
System.out.println(html);//这里我们就可能输出登录后的网页源代码了
}
}
蟒蛇版本:
#encoding:utf-8
import urllib
import urllib2
data={'username':'admin','password':'123456'}
data=urllib.urlencode(data)
response = urllib2.urlopen('http://localhost:8080/loginDemo/login',data=data)//登录
cookie = response.info()['set-cookie']//获得登录后的cookie
jsessionId = cookie.split(';')[0].split('=')[-1]//从cookie获得sessionId
html = response.read()
if html=='error':
print('用户名密码错误!')
elif html=='success':
headers = {'Cookie':'JSESSIONID='+jsessionId}//请求头
request =urllib2.Request('http://localhost:8080/loginDemo/index.jsp',headers=headers)
html = urllib2.urlopen(request).read()
print(html)//输出登录后的页面源码
我们可以清楚地看到python的优势,与java相比,它至少会写一半的代码。当然,这既是java的优势,也是java的劣势。优点是更灵活,程序员可以更好地控制底层代码的实现。,缺点是不容易上手,技术要求太高。因此,如果您是数据捕获的新手,我强烈建议您学习 python。
方法二:模拟浏览器操作
优点: 1、类似用户操作,不易被服务器检测到。
2、对于登录的网站,即使经过N层加密,也不需要考虑其加密算法。
3、可以随时获取当前页面各元素的最新状态。
缺点: 1、速度稍慢。
这里有几个很好的模拟浏览器操作的库:
C# 浏览器控件:
如果你学过c#winform,相信你一定不会对webbrower控件感到陌生,它是一个浏览器,内部驱动其实就是ie的驱动。
他可以在DOM模式下随时解析当前文档(网页文档对象),不仅可以获取相关的Element对象,还可以修改元素对象,甚至可以调用方法,比如onclick方法、onsubmit等。 ,或者直接调用页面js方法。
webbrower的C#操作代码:
webBrowser1.Navigate("https://localhost//index.html");//加载一个页面
需要注意的是:不要直接执行以下代码,因为网页加载需要时间,建议以下代码写到webBrowser1_DocumentCompleted(加载完成)事件中:
webBrowser1.Document.GetElementById("username").InnerText="admin";//在网页中找到id为username的元素,设置其文本为admin
webBrowser1.Document.GetElementById("password").InnerText = "123456";//在网页中找到id为password的元素,设置其文本为123456
webBrowser1.Document.InvokeScript("loginEncrypt");//调用网页js函数:loginEncrypt.
因为有些页面可能对IE不够友好,或者IE版本太低,甚至是安全证书,那么这个方案可能会通过。
我们可以直接使用selenium库来使用操作系统中真正的浏览器,比如chrome浏览器,selenuim支持多语言开发,以python调用selenium为例,selenium是直接操作我们系统中的浏览器,但是我们需要确保浏览器安装了相应的驱动。
但是,在实际开发中,有时我们可能不想看到这个浏览器界面。在这里,我可以给大家推荐一款无需界面直接在cmd中运行的后台浏览器,那就是phantomjs。
这样我们就可以用python+selenium+phantomjs来模拟浏览器的操作了,看不到界面了。由于phantomjs没有接口,所以会比一般的浏览器快很多。
互联网上有很多信息。我暂时不会谈论它。我不会在这里过多解释。你可以看看:
三、Fidderscript:
fiddler 是一个非常强大的数据采集工具。它不仅可以捕获当前系统中的http请求,还可以提供安全证书。所以,有时候,如果我们在抓包过程中遇到安全证书错误,我们不妨打开 fidder 让他给你提供证书,说不定你就接近成功了。
让人更厉害的是fidderscript,它可以在抓取请求后进行系统操作,比如将请求的数据保存到硬盘。或者在请求之前,修改请求头,可以说是一个强大的抓取工具。这样,我们用fidder配合前面的方法,相信大部分问题都可以解决。并且他的语法和Clike系列的差不多,类库也和c#大同小异。相信熟悉C#的同学会很快上手fiddlerscript。
提琴手: