c#抓取网页数据(几个自己研究出来的抓数据的技术,欢迎大家指正补充哈哈! )
优采云 发布时间: 2021-12-29 19:15c#抓取网页数据(几个自己研究出来的抓数据的技术,欢迎大家指正补充哈哈!
)
我也对数据抓取有一些研究。现在我分享一些我研究过的数据抓取技术。可能有很多缺点。欢迎指正并补充哈哈!
方法一:直接抓取网页源码
优点:速度快。
缺点: 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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return html.toString();}//发送post请求,并返回请求后的cookieprivate 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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.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-8import urllibimport urllib2data={'username':'admin','password':'123456'}data=urllib.urlencode(data)response = urllib2.urlopen('http://localhost:8080/loginDemo/login',data=data)//登录cookie = response.info()['set-cookie']//获得登录后的cookiejsessionId = cookie.split(';')[0].split('=')[-1]//从cookie获得sessionIdhtml = 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方法。
网页浏览器操作的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没有界面,会比普通浏览器快很多。
网上的资料很多,一时半会解释不清。我不会在这里解释太多。你可以看看:
三、Fidder脚本:
fidder 是一个非常强大的数据捕获工具。它不仅可以捕获当前系统中的http请求,还可以提供安全证书。所以,有时候,如果我们在爬取过程中遇到安全证书错误,我们不妨打开fidder,让他给你提供一个证书,说不定你就快成功了。
更强大的是 fdder 脚本,它可以在捕获请求后执行系统操作,例如将请求的数据保存到硬盘。或者在请求之前修改请求头,可以说是一个强大的工具。这样我们之前用fdder配合各种方法,相信大部分问题都可以解决。而且他的语法和C like系列语法类似,类库和c#大体相同,相信熟悉C#的同学会很快上手fiddler脚本。
fider 脚本: