php抓取网页json数据(几个自己研究出来的抓数据的技术,欢迎大家指正补充哈哈!)
优采云 发布时间: 2021-11-01 03:09php抓取网页json数据(几个自己研究出来的抓数据的技术,欢迎大家指正补充哈哈!)
还有一个关于数据抓取的小研究。现在我分享一些我研究过的数据抓取技术。可能有很多缺点。欢迎大家指正并补充哈哈!
方法一:直接抓取网页源码
优点:速度快。
缺点: 1、由于速度快,容易被服务器检测,可能会限制当前的ip抓取。为此,您可以尝试使用 ip 代码来解决它。
2、如果要抓取的数据是在网页加载后,js修改了网页元素,无法抓取。
3、遇到一些*敏*感*词*的网站抓取,如果登录后需要抓取页面,可能需要破解服务器端账号加密算法和各种加密算法,测试技术性。
适用场景:网页是完全静态的,第一次加载网页时就加载了你要抓取的数据。涉及登录或权限操作的类似页面未加密或简单加密。
当然,如果你为这个网页抓取的数据是通过接口获取的json,那你会更开心,直接抓取json页面即可。
对于一个登录页面,我们如何获取他的登录页面背后的源代码?
首先,我想介绍一下,当会话保存帐户信息时,服务器如何确定用户的身份。
首先,用户登录成功后,服务器会在session中保存用户当前的session信息,每个session都有一个唯一的标识sessionId。当用户访问该页面时,会话创建后,服务器返回的 sessionId 会被接收并保存在 cookie 中。因此,我们可以用chrome浏览器打开勾选项,查看当前页面的jsessionId。用户下次访问需要登录的页面时,用户发送的请求头会附加这个sessionId,服务器端可以通过这个sessionId来判断用户的身份。
在这里,我搭建了一个简单的jsp登录页面,登录后的账户信息保存在服务端会话中。
思路:1.登录。2.登录成功后获取cookies。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#webbrower 控件:
如果你学过c#winform,相信你对webbrower控件永远不会陌生。是浏览器,内部驱动其实就是IE驱动。
他可以随时在dom模式下解析当前文档(网页文档对象),不仅可以获取相关的Element对象,还可以修改元素对象,甚至调用方法,比如onclick方法,onsubmit等,或者直接调用页面js方法。
web浏览器的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版本太低,甚至安全证书等问题,那么这个解决方案可能会通过。
我们可以直接使用selenium库来操作操作系统中真实的浏览器,比如chrome浏览器,selenuim支持多语言开发,以python调用selenium为例,selenium就是直接操作我们系统中的浏览器,但是我们需要确保浏览器安装了相应的Drive。
但是,在实际开发中,有时我们可能不想看到这样的浏览器界面。这里可以给大家推荐一个后台浏览器,直接在cmd里面操作。没有接口,就是phantomjs。
这样我们就可以用python+selenium+phantomjs在不看界面的情况下模拟浏览器的操作。由于phantomjs没有界面,所以会比普通浏览器快很多。
网上资料很多,一时无法解释,这里就不过多解释了,大家可以看看:
三、Fidderscript:
fidder 是一个非常强大的数据捕获工具。它不仅可以捕获当前系统中的http请求,还可以提供安全证书。所以,有时候,如果我们在爬取的过程中遇到安全证书错误,我们不妨打开fidder,让他给你提供一个证书,说不定你就快成功了。
更强大的是fidderscript,它可以在捕获请求后执行系统操作,例如将请求的数据保存到硬盘。或者在请求之前修改请求头,可以说是一个强大的抓取工具。这样我们之前用fdder配合各种方法,相信大部分问题都可以解决。而且他的语法和Clike系列的语法差不多,类库和c#大同小异,相信熟悉C#的同学会很快上手fiddlerscript。
附注: