java爬虫抓取动态网页

java爬虫抓取动态网页

java爬虫抓取动态网页(Python却是最常用的,你知道为什么吗?和python教程入门学习)

网站优化优采云 发表了文章 • 0 个评论 • 54 次浏览 • 2021-12-25 03:12 • 来自相关话题

  java爬虫抓取动态网页(Python却是最常用的,你知道为什么吗?和python教程入门学习)
  说起网络爬虫,相信大家都不陌生。爬虫可以爬取某个网站或者某个应用的内容,提取有用的价值信息。很多编程语言都可以用来实现爬虫,但最常用的是Python。你知道为什么吗?一起来看看python教程的入门学习吧~
  
  与C、Python 和C 相比Python 是C 开发的语言,但在使用方面,Python 的库完整方便,而C 语言则麻烦很多。要实现同样的功能,Python 只需要 10 行代码,而 C 语言可能需要 100 行甚至更多。但在运行速度方面,C语言更胜一筹。
  对比Python和Java,Java有很多解析器,对网页解析的支持非常好。Java 也有爬虫相关的库,但没有 Python 多。不过就爬虫的效果而言,Java和Python都可以做到,只是工程量不同,实现的方式也不同。如果需要处理复杂的网页,解析网页内容生成结构化数据,或者微调网页内容,java会更合适。
  Python与其他语言没有本质区别,优势在于Python语法简单明了,开发效率高。另外,python语言的流行还有几个原因:
  1. 抓取网页的界面简单;
  与其他动态脚本语言相比,Python 提供了更完善的访问网页文档的 API;与其他静态编程语言相比,Python 拥有更简洁的网页抓取界面。
  2.强大的第三方库
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这时候就需要模拟User Agent的行为来构造合适的请求,比如模拟用户登录,模拟Session/Cookie的存储和设置。Python 中有出色的第三方包可以帮助您完成它,例如 Requests 或 Mechanize。
  3.数据处理快捷方便
  抓取到的网页通常需要进行处理,例如过滤Html标签、提取文本等。Python 的 Beautiful Soup 提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。其实很多语言和工具都可以做到以上功能,但是Python可以做到最快最干净。
  如何领取python福利教程:
  1、喜欢+评论(勾选“同时转发”)
  2、关注小编。并回复私信关键词[19]
  (一定要发私信哦~点我头像看私信按钮) 查看全部

  java爬虫抓取动态网页(Python却是最常用的,你知道为什么吗?和python教程入门学习)
  说起网络爬虫,相信大家都不陌生。爬虫可以爬取某个网站或者某个应用的内容,提取有用的价值信息。很多编程语言都可以用来实现爬虫,但最常用的是Python。你知道为什么吗?一起来看看python教程的入门学习吧~
  
  与C、Python 和C 相比Python 是C 开发的语言,但在使用方面,Python 的库完整方便,而C 语言则麻烦很多。要实现同样的功能,Python 只需要 10 行代码,而 C 语言可能需要 100 行甚至更多。但在运行速度方面,C语言更胜一筹。
  对比Python和Java,Java有很多解析器,对网页解析的支持非常好。Java 也有爬虫相关的库,但没有 Python 多。不过就爬虫的效果而言,Java和Python都可以做到,只是工程量不同,实现的方式也不同。如果需要处理复杂的网页,解析网页内容生成结构化数据,或者微调网页内容,java会更合适。
  Python与其他语言没有本质区别,优势在于Python语法简单明了,开发效率高。另外,python语言的流行还有几个原因:
  1. 抓取网页的界面简单;
  与其他动态脚本语言相比,Python 提供了更完善的访问网页文档的 API;与其他静态编程语言相比,Python 拥有更简洁的网页抓取界面。
  2.强大的第三方库
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这时候就需要模拟User Agent的行为来构造合适的请求,比如模拟用户登录,模拟Session/Cookie的存储和设置。Python 中有出色的第三方包可以帮助您完成它,例如 Requests 或 Mechanize。
  3.数据处理快捷方便
  抓取到的网页通常需要进行处理,例如过滤Html标签、提取文本等。Python 的 Beautiful Soup 提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。其实很多语言和工具都可以做到以上功能,但是Python可以做到最快最干净。
  如何领取python福利教程:
  1、喜欢+评论(勾选“同时转发”)
  2、关注小编。并回复私信关键词[19]
  (一定要发私信哦~点我头像看私信按钮)

java爬虫抓取动态网页( 动态网页爬虫技术一之API请求法安装selenium模块下载(组图))

网站优化优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2021-12-25 02:04 • 来自相关话题

  java爬虫抓取动态网页(
动态网页爬虫技术一之API请求法安装selenium模块下载(组图))
  
  在本次讲座中,我将解释一个稍微复杂一些的爬虫,即动态网页的爬虫。
  动态网页技术介绍
  动态网络爬虫技术一API请求方式
  动态网络爬虫技术二模拟浏览器方法
  安装 selenium 模块下载
  谷歌浏览器驱动安装
  ChromeDriver以某宝的松鼠店为例,抓取“坚果炒货”的产品名称、价格、销量和评论数
  课后作业
  关于作者
  动态网页技术介绍
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。
  值得强调的是,不要将动态网页与页面内容是否动态混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果无关。动态网页也可以是纯文本内容,也可以收录各种动画内容。这些只是网页的细节。内容的呈现形式,无论网页是否有动态效果,只要是使用动态网站技术生成的网页,都可以称为动态网页。(解释来源:百度百科-“动态网页”,如果链接失败请访问:%E5%8A%A8%E6%80%81%E7%BD%91%E9%A1%B5/6327050?fr=aladdin )
  
  互联网每天都在蓬勃发展。数以万计的网络平台如雨后春笋般涌现。不同的平台有不同的权限和偏好,不同的用户可以推出不同的个性化内容。传统的静态网页似乎早已无法满足社会的需求。于是,动态网页技术应运而生。当然,在对网页加载速度要求越来越高的今天,异步加载已经成为很多大型网站的首选。比如各大电商平台、知识型网站、社交平台等,都广泛采用了异步加载的动态技术。简单的说就是一些随着时间和要求而变化的内容,比如某宝的商品价格、评论、
  对于这种类型的动态页面,如果我们使用前面提到的静态网页的爬虫方法,可能得不到任何结果,因为异步加载的内容所在的位置多是请求内容的一段JS代码。在一定的触发操作下,这些JS代码开始工作,从数据库中提取出相应的数据,放置在网页框架中的相应位置,从而最终拼接成一个我们可以看到的完整页面。
  动态网络爬虫技术一API请求方式
  看似比较复杂的操作,看似给我们的爬虫带来了很大的麻烦,但实际上它们也可能给我们带来很大的便利。我们只需要找到JS请求的API,并按照一定的要求发送带有有效参数的请求就可以得到最干净的数据,而不是像以前那样从嵌套的HTML代码中慢慢解析我们想要的。所需数据。
  这里我们以上面提到的豆瓣电影(如果链接失败,请访问:#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0)为例制作一个分析,提取豆瓣前100部电影的名字和评分以及它们的地址。
  
  这是近期热门电影按人气排序的截图。每个月都有不同的新电影上映。每部电影每天都会以口碑效应呈现不同的人气排名。如果这个页面是静态网页,那么豆瓣的程序员是不是很辛苦,每天都要上网修改这个页面。因此,我们可以大胆猜测这是一个动态页面。但仅仅猜测是行不通的,我们必须证明这一点。这里我们将使用第二讲中提到的谷歌开发者工具。按F12或在网页空白处右击选择勾选(N),或按键盘上的组合键Ctrl + Shift + I来召唤我们的神器。如下所示:
  
  今天我们不再使用左上角的鼠标按钮,而是使用红色框中的网络。下面是网页加载的所有文件,如下图所示:
  
  如果下面没有结果,您需要在打开 Google Developer Tools 的同时刷新网页。
  
  如上图所示,我们可以点击上方小红框中的“XHR”按钮,过滤掉这个网页中异步加载的内容。至于哪个是我们想要的,这是个问题。看左边的地址,我们似乎没有看到线索,所以我们一一点击。. . 经过枚举,我们发现第三个就是我们想要的,其内容如下图所示:
  
  我们可以看到这个链接中收录的内容是以JSON格式显示的。这时候我们有了一个大致的思路,就是用requests模块下载这个链接的内容,然后用Python的json模块。解析。
  然而,这似乎是一页内容。计数中只有 20 部电影。我们想要的是前 100 部电影。我们应该做什么?
  没办法,毕竟是动态网页,可以根据请求更改内容,这里也没有登录操作,打开网页就可以看到,那我们能不能把网址改成进入下一页甚至下一页?页面的内容是什么?当然可以,不然我就写不下去了!
  让我们仔细看看这个 URL 中传递的参数:
  
  这时候我们可能不知道这五个参数是什么,但是我们可以找到规则,所以现在回到原来的网页,点击页面底部的“加载更多”,然后回到开发者工具,哇,多了一个网址,和刚才说的一样长,内容也一样长:
  
  此 URL 还传递五个参数:
  
  唯一的区别是名为“page_start”的关键字的值发生了变化。一个简单的翻译可能是页面的开头。看上面的“page_limit”,大概是指页数限制。查看右侧的响应内容。这个页面已经过了20个条目,也就是说“page_limit”是一个页面的条目数量限制,也就是20。这个数据不变,而“page_start”是在这个页面的条目数量这个页面的开头,那我们要不要把这个“page_start”改一下就可以得到下面的内容了?是的。
  老规矩,先写个代码
  # -*- coding: utf-8 -*-
import requests
import jsonfor i in range(5):
page_start = str(i * 20) # 注释1
url = 'https://movie.douban.com/j/sea ... 39%3B + page_start # 注释2
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
response = requests.get(url=url, headers=headers, verify=False)
content = response.content.decode()
content_list = json.loads(content)['subjects'] # 注释3for item in content_list: # 注释4
title = item['title'] #注释5
rate = item['rate'] # 注释6
link = item['url'] # 注释7
print(title, rate, link)
  
  最后,可以使用标准输入流写入txt文件,也可以使用xlwt模块写入EXCEL,也可以使用pymysql模块写入Mysql数据库,具体方法免费,请自行百度你自己。
  至此,这种通过查找API并传递有效参数来重放API的方法已经介绍给大家了。这是一个非常通用的方法。它可以在很多网站中使用,并且速度非常快,并且具有最精简的结果。.
  动态网络爬虫技术二模拟浏览器方法
  虽然我们上面提到的API请求方式简单易用,速度快,但并不是所有的网站都会使用这种异步加载的方式来实现网站,有的网站会采取反爬虫措施来对付爬虫,比如常见的验证码。验证码虽然主要是用来防止CSRF攻击,但也有网站用来对付爬虫,比如某宝。这时候,我们将介绍另一个神器,Python 的 Selenium 模块。
  Selenium 是一种用于 Web 应用程序测试的工具。Selenium 测试直接在浏览器中运行,就像真实用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11), Mozilla Firefox, Safari, Google Chrome, Opera等。本工具的主要功能包括:测试与浏览器的兼容性-测试您的应用程序可以在不同的浏览器和操作系统上运行良好测试系统功能-创建回归测试以验证软件功能和用户需求支持自动记录动作和自动生成.Net、Java、Perl等多种语言的测试脚本。 (说明来自:百度百科-《硒》,链接失效请点击)
  简单来说,Selenium 是一个主要用于自动化测试的工具。可以配合浏览器驱动运行在各个浏览器中,根据代码自动模拟人为操作,获取或控制网页元素。当然,Selenium 不是 Python 的产品,而是一个独立的项目。Python 提供对 Selenium 的支持。(您可以自行访问Selenium的主页,如果链接无效,请点击)
  安装硒模块
  要使用像Selenium这样的第三方工具,我们必须先安装它,这里仍然使用pip工具。以管理员权限运行命令行,输入pip install selenium。稍等片刻,即可完成安装。如果觉得连接官方pypi镜像的网络慢,可以使用国内豆瓣的镜像源,pip install selenium -i,加上这个-i参数和豆瓣pypi镜像的地址就够了。如果要默认使用豆瓣镜像源,请百度修改方法。
  下载谷歌浏览器驱动程序
  安装成功后,我们需要安装下一个必备的东西,浏览器驱动。前面说过,selenium需要配合浏览器驱动,所以我们以安装Google Chrome Driver为例。
  首先,我们需要检查我们的谷歌浏览器版本。这可以在谷歌的“帮助”中查看。具体方法是打开Chrome,点击右上角的三个点状按钮,然后在弹出的菜单中选择帮助。(E) -> 关于谷歌浏览器 (G) 如下图:
  
  笔者浏览器更新到最新版本63,老版本操作方法大致相同。
  点击信息上的开关后,我们可以看到当前的Chrome版本。下图是一个例子:
  
  Chrome 是在不断升级的,所以相应的驱动也要不断的升级,适配 Chrome 的版本。这里需要找到对应的ChromeDriver版本映射,推荐一个持续更新的CSDN博客(如果链接失效请点击:),根据版本映射表,下载对应版本的ChromeDriver,下载地址1()(如果链接失效,请访问:),下载地址2()(链接失效请访问:)。
  安装 ChromeDriver
  这里需要配置环境变量。如第一讲所述,为“Path”添加一行值。
  首先,我们需要找到Chrome的安装位置。最简单的方法是在桌面找到谷歌浏览器的快捷方式,右击选择“打开文件位置”打开。比如我这里打开的路径是C:\Program Files(x86)\Google\Chrome\Application,然后我会在Path中添加这个路径。然后,我们需要将下载的ChromeDriver解压到exe程序,将单独的exe程序复制到刚才的路径下,如下图:
  
  至此,ChromeDriver 安装完成。我们可以在命令行输入命令python进入python交互环境进行测试,如下图所示:
  
  如果你的谷歌浏览器自动打开并跳转到百度主页,那么恭喜~
  以某宝的松鼠店为例,爬取“坚果炒货”的产品名称、价格、销量和评论数
  此页面的 URL 是:#TmshopSrchNav
  老规矩,先放一段代码:
  # -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Chrome() # 注释1
url = 'https://sanzhisongshu.tmall.co ... 39%3B
driver.maximize_window() # 注释2
driver.get(url) # 注释3
dl_list = driver.find_elements_by_class_name('item') # 注释4
for dl in dl_list:
name = dl.find_element_by_css_selector("[class='item-name J_TGoldData']").text # 注释5
price = dl.find_element_by_class_name('cprice-area').text # 注释6
sale = dl.find_element_by_class_name('sale-area').text # 注释7
comment = dl.find_element_by_xpath('//*[@id="J_ShopSearchResult"]/div/div[3]/div[1]/dl[1]/dd[2]/div/h4/a/span').text # 注释8
print(name, price, sale, comment)
driver.close() # 注释9
  
  XPath 是 XML 路径语言,它是一种用于确定 XML(标准通用标记语言的子集)文档某个部分的位置的语言。XPath 基于 XML 树结构,具有不同类型的节点,包括元素节点、属性节点和文本节点,提供在数据结构树中查找节点的能力。最初,XPath 的初衷是将其用作 XPointer 和 XSLT 之间的通用语法模型。但是 XPath 很快就被开发人员采用为一种小型查询语言。(说明来自:百度百科-“XPath”,如果链接失败,请访问:)
  
  这个例子的最终结果如下:
  
  大家依然可以自由选择数据的存储方式。
  这里需要注意的是,使用selenium进行数据爬取可能比之前的API请求方式慢很多。打开相应的窗口后,窗口中可能长时间没有动作,但这不一定是错误或程序卡住的迹象,也可能是程序在疯狂搜索网页元素。在此过程中,如果您不确定是否有错误,请不要进行其他操作,以免有时会导致元素失去焦点而导致莫名其妙的错误。
  当然,硒的作用远不止这些。它可以模拟几乎人在网页上可以做出的行为,包括点击、打字等行为。这个比较适合一些网站填写验证码的情况,大家可以自行寻找更多有趣的内容。本次讲座到此结束。感谢您的耐心阅读。
  课后作业
  这里有两个小作业给大家,有兴趣的可以自己测试一下。
  请使用API​​请求方式在QQ音乐上查找付费下载歌曲,无需登录账号即可下载歌曲。请用selenium爬取知乎首页热点话题或回答100个话题。
  关于作者
  作者是即将毕业的大四,自学爬虫,作为多个爬虫项目的主要开发者,对各种爬虫有一定的了解和项目经验,目前正在自学分布式爬虫的内容,以后会继续为大家关注更新。同时作者也是一位狂热的信息安全爱好者。谢谢你的支持。 查看全部

  java爬虫抓取动态网页(
动态网页爬虫技术一之API请求法安装selenium模块下载(组图))
  
  在本次讲座中,我将解释一个稍微复杂一些的爬虫,即动态网页的爬虫。
  动态网页技术介绍
  动态网络爬虫技术一API请求方式
  动态网络爬虫技术二模拟浏览器方法
  安装 selenium 模块下载
  谷歌浏览器驱动安装
  ChromeDriver以某宝的松鼠店为例,抓取“坚果炒货”的产品名称、价格、销量和评论数
  课后作业
  关于作者
  动态网页技术介绍
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。
  值得强调的是,不要将动态网页与页面内容是否动态混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果无关。动态网页也可以是纯文本内容,也可以收录各种动画内容。这些只是网页的细节。内容的呈现形式,无论网页是否有动态效果,只要是使用动态网站技术生成的网页,都可以称为动态网页。(解释来源:百度百科-“动态网页”,如果链接失败请访问:%E5%8A%A8%E6%80%81%E7%BD%91%E9%A1%B5/6327050?fr=aladdin )
  
  互联网每天都在蓬勃发展。数以万计的网络平台如雨后春笋般涌现。不同的平台有不同的权限和偏好,不同的用户可以推出不同的个性化内容。传统的静态网页似乎早已无法满足社会的需求。于是,动态网页技术应运而生。当然,在对网页加载速度要求越来越高的今天,异步加载已经成为很多大型网站的首选。比如各大电商平台、知识型网站、社交平台等,都广泛采用了异步加载的动态技术。简单的说就是一些随着时间和要求而变化的内容,比如某宝的商品价格、评论、
  对于这种类型的动态页面,如果我们使用前面提到的静态网页的爬虫方法,可能得不到任何结果,因为异步加载的内容所在的位置多是请求内容的一段JS代码。在一定的触发操作下,这些JS代码开始工作,从数据库中提取出相应的数据,放置在网页框架中的相应位置,从而最终拼接成一个我们可以看到的完整页面。
  动态网络爬虫技术一API请求方式
  看似比较复杂的操作,看似给我们的爬虫带来了很大的麻烦,但实际上它们也可能给我们带来很大的便利。我们只需要找到JS请求的API,并按照一定的要求发送带有有效参数的请求就可以得到最干净的数据,而不是像以前那样从嵌套的HTML代码中慢慢解析我们想要的。所需数据。
  这里我们以上面提到的豆瓣电影(如果链接失败,请访问:#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0)为例制作一个分析,提取豆瓣前100部电影的名字和评分以及它们的地址。
  
  这是近期热门电影按人气排序的截图。每个月都有不同的新电影上映。每部电影每天都会以口碑效应呈现不同的人气排名。如果这个页面是静态网页,那么豆瓣的程序员是不是很辛苦,每天都要上网修改这个页面。因此,我们可以大胆猜测这是一个动态页面。但仅仅猜测是行不通的,我们必须证明这一点。这里我们将使用第二讲中提到的谷歌开发者工具。按F12或在网页空白处右击选择勾选(N),或按键盘上的组合键Ctrl + Shift + I来召唤我们的神器。如下所示:
  
  今天我们不再使用左上角的鼠标按钮,而是使用红色框中的网络。下面是网页加载的所有文件,如下图所示:
  
  如果下面没有结果,您需要在打开 Google Developer Tools 的同时刷新网页。
  
  如上图所示,我们可以点击上方小红框中的“XHR”按钮,过滤掉这个网页中异步加载的内容。至于哪个是我们想要的,这是个问题。看左边的地址,我们似乎没有看到线索,所以我们一一点击。. . 经过枚举,我们发现第三个就是我们想要的,其内容如下图所示:
  
  我们可以看到这个链接中收录的内容是以JSON格式显示的。这时候我们有了一个大致的思路,就是用requests模块下载这个链接的内容,然后用Python的json模块。解析。
  然而,这似乎是一页内容。计数中只有 20 部电影。我们想要的是前 100 部电影。我们应该做什么?
  没办法,毕竟是动态网页,可以根据请求更改内容,这里也没有登录操作,打开网页就可以看到,那我们能不能把网址改成进入下一页甚至下一页?页面的内容是什么?当然可以,不然我就写不下去了!
  让我们仔细看看这个 URL 中传递的参数:
  
  这时候我们可能不知道这五个参数是什么,但是我们可以找到规则,所以现在回到原来的网页,点击页面底部的“加载更多”,然后回到开发者工具,哇,多了一个网址,和刚才说的一样长,内容也一样长:
  
  此 URL 还传递五个参数:
  
  唯一的区别是名为“page_start”的关键字的值发生了变化。一个简单的翻译可能是页面的开头。看上面的“page_limit”,大概是指页数限制。查看右侧的响应内容。这个页面已经过了20个条目,也就是说“page_limit”是一个页面的条目数量限制,也就是20。这个数据不变,而“page_start”是在这个页面的条目数量这个页面的开头,那我们要不要把这个“page_start”改一下就可以得到下面的内容了?是的。
  老规矩,先写个代码
  # -*- coding: utf-8 -*-
import requests
import jsonfor i in range(5):
page_start = str(i * 20) # 注释1
url = 'https://movie.douban.com/j/sea ... 39%3B + page_start # 注释2
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
response = requests.get(url=url, headers=headers, verify=False)
content = response.content.decode()
content_list = json.loads(content)['subjects'] # 注释3for item in content_list: # 注释4
title = item['title'] #注释5
rate = item['rate'] # 注释6
link = item['url'] # 注释7
print(title, rate, link)
  
  最后,可以使用标准输入流写入txt文件,也可以使用xlwt模块写入EXCEL,也可以使用pymysql模块写入Mysql数据库,具体方法免费,请自行百度你自己。
  至此,这种通过查找API并传递有效参数来重放API的方法已经介绍给大家了。这是一个非常通用的方法。它可以在很多网站中使用,并且速度非常快,并且具有最精简的结果。.
  动态网络爬虫技术二模拟浏览器方法
  虽然我们上面提到的API请求方式简单易用,速度快,但并不是所有的网站都会使用这种异步加载的方式来实现网站,有的网站会采取反爬虫措施来对付爬虫,比如常见的验证码。验证码虽然主要是用来防止CSRF攻击,但也有网站用来对付爬虫,比如某宝。这时候,我们将介绍另一个神器,Python 的 Selenium 模块。
  Selenium 是一种用于 Web 应用程序测试的工具。Selenium 测试直接在浏览器中运行,就像真实用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11), Mozilla Firefox, Safari, Google Chrome, Opera等。本工具的主要功能包括:测试与浏览器的兼容性-测试您的应用程序可以在不同的浏览器和操作系统上运行良好测试系统功能-创建回归测试以验证软件功能和用户需求支持自动记录动作和自动生成.Net、Java、Perl等多种语言的测试脚本。 (说明来自:百度百科-《硒》,链接失效请点击)
  简单来说,Selenium 是一个主要用于自动化测试的工具。可以配合浏览器驱动运行在各个浏览器中,根据代码自动模拟人为操作,获取或控制网页元素。当然,Selenium 不是 Python 的产品,而是一个独立的项目。Python 提供对 Selenium 的支持。(您可以自行访问Selenium的主页,如果链接无效,请点击)
  安装硒模块
  要使用像Selenium这样的第三方工具,我们必须先安装它,这里仍然使用pip工具。以管理员权限运行命令行,输入pip install selenium。稍等片刻,即可完成安装。如果觉得连接官方pypi镜像的网络慢,可以使用国内豆瓣的镜像源,pip install selenium -i,加上这个-i参数和豆瓣pypi镜像的地址就够了。如果要默认使用豆瓣镜像源,请百度修改方法。
  下载谷歌浏览器驱动程序
  安装成功后,我们需要安装下一个必备的东西,浏览器驱动。前面说过,selenium需要配合浏览器驱动,所以我们以安装Google Chrome Driver为例。
  首先,我们需要检查我们的谷歌浏览器版本。这可以在谷歌的“帮助”中查看。具体方法是打开Chrome,点击右上角的三个点状按钮,然后在弹出的菜单中选择帮助。(E) -> 关于谷歌浏览器 (G) 如下图:
  
  笔者浏览器更新到最新版本63,老版本操作方法大致相同。
  点击信息上的开关后,我们可以看到当前的Chrome版本。下图是一个例子:
  
  Chrome 是在不断升级的,所以相应的驱动也要不断的升级,适配 Chrome 的版本。这里需要找到对应的ChromeDriver版本映射,推荐一个持续更新的CSDN博客(如果链接失效请点击:),根据版本映射表,下载对应版本的ChromeDriver,下载地址1()(如果链接失效,请访问:),下载地址2()(链接失效请访问:)。
  安装 ChromeDriver
  这里需要配置环境变量。如第一讲所述,为“Path”添加一行值。
  首先,我们需要找到Chrome的安装位置。最简单的方法是在桌面找到谷歌浏览器的快捷方式,右击选择“打开文件位置”打开。比如我这里打开的路径是C:\Program Files(x86)\Google\Chrome\Application,然后我会在Path中添加这个路径。然后,我们需要将下载的ChromeDriver解压到exe程序,将单独的exe程序复制到刚才的路径下,如下图:
  
  至此,ChromeDriver 安装完成。我们可以在命令行输入命令python进入python交互环境进行测试,如下图所示:
  
  如果你的谷歌浏览器自动打开并跳转到百度主页,那么恭喜~
  以某宝的松鼠店为例,爬取“坚果炒货”的产品名称、价格、销量和评论数
  此页面的 URL 是:#TmshopSrchNav
  老规矩,先放一段代码:
  # -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Chrome() # 注释1
url = 'https://sanzhisongshu.tmall.co ... 39%3B
driver.maximize_window() # 注释2
driver.get(url) # 注释3
dl_list = driver.find_elements_by_class_name('item') # 注释4
for dl in dl_list:
name = dl.find_element_by_css_selector("[class='item-name J_TGoldData']").text # 注释5
price = dl.find_element_by_class_name('cprice-area').text # 注释6
sale = dl.find_element_by_class_name('sale-area').text # 注释7
comment = dl.find_element_by_xpath('//*[@id="J_ShopSearchResult"]/div/div[3]/div[1]/dl[1]/dd[2]/div/h4/a/span').text # 注释8
print(name, price, sale, comment)
driver.close() # 注释9
  
  XPath 是 XML 路径语言,它是一种用于确定 XML(标准通用标记语言的子集)文档某个部分的位置的语言。XPath 基于 XML 树结构,具有不同类型的节点,包括元素节点、属性节点和文本节点,提供在数据结构树中查找节点的能力。最初,XPath 的初衷是将其用作 XPointer 和 XSLT 之间的通用语法模型。但是 XPath 很快就被开发人员采用为一种小型查询语言。(说明来自:百度百科-“XPath”,如果链接失败,请访问:)
  
  这个例子的最终结果如下:
  
  大家依然可以自由选择数据的存储方式。
  这里需要注意的是,使用selenium进行数据爬取可能比之前的API请求方式慢很多。打开相应的窗口后,窗口中可能长时间没有动作,但这不一定是错误或程序卡住的迹象,也可能是程序在疯狂搜索网页元素。在此过程中,如果您不确定是否有错误,请不要进行其他操作,以免有时会导致元素失去焦点而导致莫名其妙的错误。
  当然,硒的作用远不止这些。它可以模拟几乎人在网页上可以做出的行为,包括点击、打字等行为。这个比较适合一些网站填写验证码的情况,大家可以自行寻找更多有趣的内容。本次讲座到此结束。感谢您的耐心阅读。
  课后作业
  这里有两个小作业给大家,有兴趣的可以自己测试一下。
  请使用API​​请求方式在QQ音乐上查找付费下载歌曲,无需登录账号即可下载歌曲。请用selenium爬取知乎首页热点话题或回答100个话题。
  关于作者
  作者是即将毕业的大四,自学爬虫,作为多个爬虫项目的主要开发者,对各种爬虫有一定的了解和项目经验,目前正在自学分布式爬虫的内容,以后会继续为大家关注更新。同时作者也是一位狂热的信息安全爱好者。谢谢你的支持。

java爬虫抓取动态网页(Java爬虫使用WebMagic框架介绍(一)_Java(图) )

网站优化优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-25 02:01 • 来自相关话题

  java爬虫抓取动态网页(Java爬虫使用WebMagic框架介绍(一)_Java(图)
)
  最近如果需要用Java写爬虫,就去学习Java爬虫了。因为之前学过Scrapy框架,所以学Java的爬虫使用的是基于Scrapy框架开发的WebMagic框架。有兴趣的可以去看看操作文档:
  这个框架是中国人开发的,所以文档都是中文的,简单易懂。
  引入WebMagic框架的方法在操作文档里,这里就不解释了(建议阅读之前先阅读操作文档文章。我导入jar包使用)
  我用的版本是0.7.3。
  
  本项目使用webmagic框架抓取网易云播放列表,并将抓取到的内容存入mysql。这个演示之前已经用 Python 实现过。有兴趣的可以看看我之前的文章文章
  webmagic的各个模块不再赘述,直接说代码实现即可(默认你已经阅读了操作文档)
  首先创建一个Site对象来配置爬虫,包括爬取间隔、重试次数、请求头等。
   private Site site = Site.me().setSleepTime(1000).setRetryTimes(3).addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0");
  然后写过程方法。流程方法是自定义爬虫逻辑的核心部分,这里制定了筛选规则。
  page.putField()方法可以将数据以key:value的形式保存,然后交给pipeline文件处理。
  后面的网站的url与第一页的url相差最后一个值,所以可以使用字符串拼接。
  然后使用 page.addTargetRequest() 方法将后续 URL 添加到抓取序列中。
  (basic是前面定义的静态成员)
  url=";cat=%E5%85%A8%E9%83%A8&limit=35&offset="
<p> public void process(Page page) {
//将数据交给pipeline文件处理
page.putField("name",page.getHtml().xpath("//li/p[@class=dec]/a/text()").all());
page.putField("src",page.getHtml().xpath("//li/p[@class=dec]/a/@href").all());
page.putField("clicknum",page.getHtml().xpath("//li//div[@class=bottom]/span[@class=nb]/text()").all());
page.putField("author",page.getHtml().xpath("//li//a[@class=nm]/text()").all());
page.putField("homepage",page.getHtml().xpath("//li//a[@class=nm]/@href").all());
//连续爬取后续网页
int flag = 35;
String nexturl = null;
for (int i=flag; i 查看全部

  java爬虫抓取动态网页(Java爬虫使用WebMagic框架介绍(一)_Java(图)
)
  最近如果需要用Java写爬虫,就去学习Java爬虫了。因为之前学过Scrapy框架,所以学Java的爬虫使用的是基于Scrapy框架开发的WebMagic框架。有兴趣的可以去看看操作文档:
  这个框架是中国人开发的,所以文档都是中文的,简单易懂。
  引入WebMagic框架的方法在操作文档里,这里就不解释了(建议阅读之前先阅读操作文档文章。我导入jar包使用)
  我用的版本是0.7.3。
  
  本项目使用webmagic框架抓取网易云播放列表,并将抓取到的内容存入mysql。这个演示之前已经用 Python 实现过。有兴趣的可以看看我之前的文章文章
  webmagic的各个模块不再赘述,直接说代码实现即可(默认你已经阅读了操作文档)
  首先创建一个Site对象来配置爬虫,包括爬取间隔、重试次数、请求头等。
   private Site site = Site.me().setSleepTime(1000).setRetryTimes(3).addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0");
  然后写过程方法。流程方法是自定义爬虫逻辑的核心部分,这里制定了筛选规则。
  page.putField()方法可以将数据以key:value的形式保存,然后交给pipeline文件处理。
  后面的网站的url与第一页的url相差最后一个值,所以可以使用字符串拼接。
  然后使用 page.addTargetRequest() 方法将后续 URL 添加到抓取序列中。
  (basic是前面定义的静态成员)
  url=";cat=%E5%85%A8%E9%83%A8&amp;limit=35&amp;offset="
<p> public void process(Page page) {
//将数据交给pipeline文件处理
page.putField("name",page.getHtml().xpath("//li/p[@class=dec]/a/text()").all());
page.putField("src",page.getHtml().xpath("//li/p[@class=dec]/a/@href").all());
page.putField("clicknum",page.getHtml().xpath("//li//div[@class=bottom]/span[@class=nb]/text()").all());
page.putField("author",page.getHtml().xpath("//li//a[@class=nm]/text()").all());
page.putField("homepage",page.getHtml().xpath("//li//a[@class=nm]/@href").all());
//连续爬取后续网页
int flag = 35;
String nexturl = null;
for (int i=flag; i

java爬虫抓取动态网页(完整的抓取示例工程可加群250108697图 )

网站优化优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-24 23:13 • 来自相关话题

  java爬虫抓取动态网页(完整的抓取示例工程可加群250108697图
)
  网站中的图片和网页本质上是一样的。图片和网页的获取本质上是根据url从网站中获取网页/图片的字节数组(byte[]),浏览器根据http响应头中的content-type信息,浏览器决定是否以网页或图片的形式显示资源。
  完整的抓图示例工程可以加入群250108697,在群文件中获取。
  示例中的代码将美食街中的图片爬取到指定文件夹,爬取结果如下图所示:
  
  核心代码:
  import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import cn.edu.hfut.dmic.webcollector.plugin.net.OkHttpRequester;
import cn.edu.hfut.dmic.webcollector.util.ExceptionUtils;
import cn.edu.hfut.dmic.webcollector.util.FileUtils;
import cn.edu.hfut.dmic.webcollector.util.MD5Utils;
import java.io.File;
/**
* WebCollector抓取图片的例子
* @author hu
*/
public class DemoImageCrawler extends BreadthCrawler {
File baseDir = new File("images");
/**
* 构造一个基于伯克利DB的爬虫
* 伯克利DB文件夹为crawlPath,crawlPath中维护了历史URL等信息
* 不同任务不要使用相同的crawlPath
* 两个使用相同crawlPath的爬虫并行爬取会产生错误
*
* @param crawlPath 伯克利DB使用的文件夹
*/
public DemoImageCrawler(String crawlPath) {
super(crawlPath, true);
//只有在autoParse和autoDetectImg都为true的情况下
//爬虫才会自动解析图片链接
getConf().setAutoDetectImg(true);
//如果使用默认的Requester,需要像下面这样设置一下网页大小上限
//否则可能会获得一个不完整的页面
//下面这行将页面大小上限设置为10M
//getConf().setMaxReceiveSize(1024 * 1024 * 10);
//添加种子URL
addSeed("http://www.meishij.net/");
//限定爬取范围
addRegex("http://www.meishij.net/.*");
addRegex("http://images.meishij.net/.*");
addRegex("-.*#.*");
addRegex("-.*\\?.*");
//设置为断点爬取,否则每次开启爬虫都会重新爬取
// demoImageCrawler.setResumable(true);
setThreads(30);
}
@Override
public void visit(Page page, CrawlDatums next) {
//根据http头中的Content-Type信息来判断当前资源是网页还是图片
String contentType = page.contentType();
//根据Content-Type判断是否为图片
if(contentType!=null && contentType.startsWith("image")){
//从Content-Type中获取图片扩展名
String extensionName=contentType.split("/")[1];
try {
byte[] image = page.content();
//根据图片MD5生成文件名
String fileName = String.format("%s.%s",MD5Utils.md5(image), extensionName);
File imageFile = new File(baseDir, fileName);
FileUtils.write(imageFile, image);
System.out.println("保存图片 "+page.url()+" 到 "+ imageFile.getAbsolutePath());
} catch (Exception e) {
ExceptionUtils.fail(e);
}
}
}
public static void main(String[] args) throws Exception {
DemoImageCrawler demoImageCrawler = new DemoImageCrawler("crawl");
demoImageCrawler.setRequester(new OkHttpRequester());
//设置为断点爬取,否则每次开启爬虫都会重新爬取
demoImageCrawler.setResumable(true);
demoImageCrawler.start(3);
}
} 查看全部

  java爬虫抓取动态网页(完整的抓取示例工程可加群250108697图
)
  网站中的图片和网页本质上是一样的。图片和网页的获取本质上是根据url从网站中获取网页/图片的字节数组(byte[]),浏览器根据http响应头中的content-type信息,浏览器决定是否以网页或图片的形式显示资源。
  完整的抓图示例工程可以加入群250108697,在群文件中获取。
  示例中的代码将美食街中的图片爬取到指定文件夹,爬取结果如下图所示:
  
  核心代码:
  import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import cn.edu.hfut.dmic.webcollector.plugin.net.OkHttpRequester;
import cn.edu.hfut.dmic.webcollector.util.ExceptionUtils;
import cn.edu.hfut.dmic.webcollector.util.FileUtils;
import cn.edu.hfut.dmic.webcollector.util.MD5Utils;
import java.io.File;
/**
* WebCollector抓取图片的例子
* @author hu
*/
public class DemoImageCrawler extends BreadthCrawler {
File baseDir = new File("images");
/**
* 构造一个基于伯克利DB的爬虫
* 伯克利DB文件夹为crawlPath,crawlPath中维护了历史URL等信息
* 不同任务不要使用相同的crawlPath
* 两个使用相同crawlPath的爬虫并行爬取会产生错误
*
* @param crawlPath 伯克利DB使用的文件夹
*/
public DemoImageCrawler(String crawlPath) {
super(crawlPath, true);
//只有在autoParse和autoDetectImg都为true的情况下
//爬虫才会自动解析图片链接
getConf().setAutoDetectImg(true);
//如果使用默认的Requester,需要像下面这样设置一下网页大小上限
//否则可能会获得一个不完整的页面
//下面这行将页面大小上限设置为10M
//getConf().setMaxReceiveSize(1024 * 1024 * 10);
//添加种子URL
addSeed("http://www.meishij.net/";);
//限定爬取范围
addRegex("http://www.meishij.net/.*");
addRegex("http://images.meishij.net/.*");
addRegex("-.*#.*");
addRegex("-.*\\?.*");
//设置为断点爬取,否则每次开启爬虫都会重新爬取
// demoImageCrawler.setResumable(true);
setThreads(30);
}
@Override
public void visit(Page page, CrawlDatums next) {
//根据http头中的Content-Type信息来判断当前资源是网页还是图片
String contentType = page.contentType();
//根据Content-Type判断是否为图片
if(contentType!=null && contentType.startsWith("image")){
//从Content-Type中获取图片扩展名
String extensionName=contentType.split("/")[1];
try {
byte[] image = page.content();
//根据图片MD5生成文件名
String fileName = String.format("%s.%s",MD5Utils.md5(image), extensionName);
File imageFile = new File(baseDir, fileName);
FileUtils.write(imageFile, image);
System.out.println("保存图片 "+page.url()+" 到 "+ imageFile.getAbsolutePath());
} catch (Exception e) {
ExceptionUtils.fail(e);
}
}
}
public static void main(String[] args) throws Exception {
DemoImageCrawler demoImageCrawler = new DemoImageCrawler("crawl");
demoImageCrawler.setRequester(new OkHttpRequester());
//设置为断点爬取,否则每次开启爬虫都会重新爬取
demoImageCrawler.setResumable(true);
demoImageCrawler.start(3);
}
}

java爬虫抓取动态网页( 零基础写Java知乎爬虫之进阶篇抓取一个网站)

网站优化优采云 发表了文章 • 0 个评论 • 75 次浏览 • 2021-12-20 03:01 • 来自相关话题

  java爬虫抓取动态网页(
零基础写Java知乎爬虫之进阶篇抓取一个网站)
  
  搭建开发环境,在项目的Build Path中导入下载的Commons-httpClient3.1.Jar、htmllexer.jar和htmlparser.jar文件。图1. 开发环境搭建HttpClient基础类 该库使用HttpClinet提供了几个支持HTTP访问的类。下面我们通过一些示例代码来熟悉和解释这些类的功能和用途。HttpClient 提供的 HTTP 访问主要通过 GetMethod 类和 PostMethod 类来实现。它们分别对应于HTT
  零基础写Java知乎爬虫进阶篇
  
  说到爬虫,使用Java自带的URLConnection可以实现一些基本的页面爬取功能,但是对于一些更高级的功能,比如重定向处理、去除HTML标签等,单独使用URLConnection是不够的。这里我们可以使用第三方jar包HttpClient。接下来我们用HttpClient写一个简单的爬到百度的demo:import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStr
  从互联网爬取邮箱的Java代码示例
  网络爬虫:其实就是一个用来获取互联网上符合规定规则的数据的程序。包day05; 导入 java.io.BufferedReader; 导入 java.io.IOException; 导入 java.io.InputStreamReader; 导入.URL; 导入java。util.ArrayList; 导入 java.util.List; 导入 java.util.regex.Matcher; 进口
  Java 爬虫实际上抓取了 网站 上的所有链接
  
  前言:在写这篇文章之前,主要看了几个类似的爬虫写法,有的写成队列,感觉不是很直观,有的只有一个请求然后页面分析,没有自动爬行。这也叫爬虫?所以我根据自己的想法写了一个简单的爬虫。一个算法介绍程序在其思想中使用了广度优先算法。对未遍历过的链接一一发起GET请求,然后响应返回的链接。页面用正则表达式解析,没有发现的新链接被取出,加入集合,在下一个循环中遍历。具体实现使用Map,键值对是链接和是否被遍历的标志。程序中使用的两个地图集
  Java爬虫抓取信息的实现
  
  今天公司有个需求,需要在指定网站查询后做一些数据抓取,所以花了一段时间写了一个demo来演示。思路很简单:就是通过Java访问链接,然后得到html字符串,然后解析链接需要的数据。从技术上讲,Jsoup 是用来方便页面解析的。当然,Jsoup 是非常方便和简单的。一行代码就知道怎么用了: Document doc = Jsoup.connect("") .data("query", "Java") //
  Java爬虫抓取京东HttpCliient+Jsoup上的手机搜索页面
  
  1. 需求及配置需求:抓取京东手机搜索页面的信息,记录每款手机的名称、价格、评论数等,形成数据表,可用于实际分析. 使用Maven项目,log4j记录日志,日志只导出到控制台。Maven依赖以下(pom.xml)org.apache.httpcomponents httpclient
  Python爬虫爬取网页图片地址示例代码
  
  本文的例子主要是抓取网页上的图片地址,如下。读取网页源码: import urllib.request def getHtml(url): html=urllib.request.urlopen(url).read() return html print(getHtml(%E5%A3%81%E7%BA%) B8&amp;ct=201326592&amp;am
  Google 抓取工具如何抓取 JavaScript 内容
  
  我们测试了 Google 爬虫如何抓取 JavaScript,这是我们从中学到的东西。认为 Google 无法处理 JavaScript?再想想。Audette Audette 分享了一系列的测试结果,他和他的同事测试了什么类型的 JavaScript 函数会被 Google 和 收录 抓取。长话短说 1. 我们进行了一系列测试,并确认 Google 可以以多种方式执行和 收录 JavaScript。我们还确认了 Google 可以渲染整个 Page 并读取 DOM,从而可以收录 动态生成内容。2. DOM
  java简单网页爬取的实现方法
  本文介绍了java中简单网页爬虫的实现方法。分享出来供大家参考。具体分析如下: 背景介绍 1 tcp 介绍 1 tcp 在网络中实现点对点传输 2 传输由ports 和sockets 提供不同类型的端口传输(例如http的端口为80) 1)sockets 可以绑定特定的端口,并提供传输功能 2) 一个端口可以连接多个socket 两个 URL 介绍 URL 对 一个简洁的表示获取资源的位置和访问方式from the Internet 是 Internet 上标准资源的地址。Internet 上的每个文件都有一个唯一的
  Python多进程爬取基金网站内容的方法分析
  本文以Python多进程方式抓取基金内容为例网站。分享给大家,供大家参考,如下:在之前的文章///article/162418.htm中,我们已经简单了解了“Python的多进程”,现在需要写爬取的内容Fund 网站(28 页)作为一种多进程方法。因为流程不是越多越好,我们打算分成三个流程。意思是:将要抓取的总共28页分成三部分。如何划分?# 初始范围 r = range(1,29) # 步长 step = 10 myList = [r[x:
  Python爬虫实现爬取京东店铺信息和下载图片功能示例
  本文介绍了Python爬虫实现爬取京东店铺信息和下载图片的功能。分享出来供大家参考,如下: 这是来自bs4 import BeautifulSoup import requests url ='+%C9%D5%CB% AE&amp;type=p&amp;vmarket=&amp;spm=875.7931836%2FA.a2227oh.d100&amp;from=mal
  使用 vbs 从剪贴板中抓取一个 URL,然后在浏览器中打开网站
  问题:您好,ScriptingGuy!如何从剪贴板中获取 URL 并在浏览器中打开网站?--CL 回答:你好,CL。这是一个非常有趣的问题,或者应该说,这是两个非常有趣的问题。因为你实际上问了两个问题。第一个问题很简单:我可以用脚本打开一个特定的网站吗?你可能已经知道答案了,我可以大声回答你,是的!下面是一个示例脚本,它将“脚本中心”的 URL 存储在名为 strURL 的变量中。然后,此脚本创建 WSHShell 对象的实例并使用 Run 查看全部

  java爬虫抓取动态网页(
零基础写Java知乎爬虫之进阶篇抓取一个网站)
  
  搭建开发环境,在项目的Build Path中导入下载的Commons-httpClient3.1.Jar、htmllexer.jar和htmlparser.jar文件。图1. 开发环境搭建HttpClient基础类 该库使用HttpClinet提供了几个支持HTTP访问的类。下面我们通过一些示例代码来熟悉和解释这些类的功能和用途。HttpClient 提供的 HTTP 访问主要通过 GetMethod 类和 PostMethod 类来实现。它们分别对应于HTT
  零基础写Java知乎爬虫进阶篇
  
  说到爬虫,使用Java自带的URLConnection可以实现一些基本的页面爬取功能,但是对于一些更高级的功能,比如重定向处理、去除HTML标签等,单独使用URLConnection是不够的。这里我们可以使用第三方jar包HttpClient。接下来我们用HttpClient写一个简单的爬到百度的demo:import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStr
  从互联网爬取邮箱的Java代码示例
  网络爬虫:其实就是一个用来获取互联网上符合规定规则的数据的程序。包day05; 导入 java.io.BufferedReader; 导入 java.io.IOException; 导入 java.io.InputStreamReader; 导入.URL; 导入java。util.ArrayList; 导入 java.util.List; 导入 java.util.regex.Matcher; 进口
  Java 爬虫实际上抓取了 网站 上的所有链接
  
  前言:在写这篇文章之前,主要看了几个类似的爬虫写法,有的写成队列,感觉不是很直观,有的只有一个请求然后页面分析,没有自动爬行。这也叫爬虫?所以我根据自己的想法写了一个简单的爬虫。一个算法介绍程序在其思想中使用了广度优先算法。对未遍历过的链接一一发起GET请求,然后响应返回的链接。页面用正则表达式解析,没有发现的新链接被取出,加入集合,在下一个循环中遍历。具体实现使用Map,键值对是链接和是否被遍历的标志。程序中使用的两个地图集
  Java爬虫抓取信息的实现
  
  今天公司有个需求,需要在指定网站查询后做一些数据抓取,所以花了一段时间写了一个demo来演示。思路很简单:就是通过Java访问链接,然后得到html字符串,然后解析链接需要的数据。从技术上讲,Jsoup 是用来方便页面解析的。当然,Jsoup 是非常方便和简单的。一行代码就知道怎么用了: Document doc = Jsoup.connect("") .data("query", "Java") //
  Java爬虫抓取京东HttpCliient+Jsoup上的手机搜索页面
  
  1. 需求及配置需求:抓取京东手机搜索页面的信息,记录每款手机的名称、价格、评论数等,形成数据表,可用于实际分析. 使用Maven项目,log4j记录日志,日志只导出到控制台。Maven依赖以下(pom.xml)org.apache.httpcomponents httpclient
  Python爬虫爬取网页图片地址示例代码
  
  本文的例子主要是抓取网页上的图片地址,如下。读取网页源码: import urllib.request def getHtml(url): html=urllib.request.urlopen(url).read() return html print(getHtml(%E5%A3%81%E7%BA%) B8&amp;ct=201326592&amp;am
  Google 抓取工具如何抓取 JavaScript 内容
  
  我们测试了 Google 爬虫如何抓取 JavaScript,这是我们从中学到的东西。认为 Google 无法处理 JavaScript?再想想。Audette Audette 分享了一系列的测试结果,他和他的同事测试了什么类型的 JavaScript 函数会被 Google 和 收录 抓取。长话短说 1. 我们进行了一系列测试,并确认 Google 可以以多种方式执行和 收录 JavaScript。我们还确认了 Google 可以渲染整个 Page 并读取 DOM,从而可以收录 动态生成内容。2. DOM
  java简单网页爬取的实现方法
  本文介绍了java中简单网页爬虫的实现方法。分享出来供大家参考。具体分析如下: 背景介绍 1 tcp 介绍 1 tcp 在网络中实现点对点传输 2 传输由ports 和sockets 提供不同类型的端口传输(例如http的端口为80) 1)sockets 可以绑定特定的端口,并提供传输功能 2) 一个端口可以连接多个socket 两个 URL 介绍 URL 对 一个简洁的表示获取资源的位置和访问方式from the Internet 是 Internet 上标准资源的地址。Internet 上的每个文件都有一个唯一的
  Python多进程爬取基金网站内容的方法分析
  本文以Python多进程方式抓取基金内容为例网站。分享给大家,供大家参考,如下:在之前的文章///article/162418.htm中,我们已经简单了解了“Python的多进程”,现在需要写爬取的内容Fund 网站(28 页)作为一种多进程方法。因为流程不是越多越好,我们打算分成三个流程。意思是:将要抓取的总共28页分成三部分。如何划分?# 初始范围 r = range(1,29) # 步长 step = 10 myList = [r[x:
  Python爬虫实现爬取京东店铺信息和下载图片功能示例
  本文介绍了Python爬虫实现爬取京东店铺信息和下载图片的功能。分享出来供大家参考,如下: 这是来自bs4 import BeautifulSoup import requests url ='+%C9%D5%CB% AE&amp;type=p&amp;vmarket=&amp;spm=875.7931836%2FA.a2227oh.d100&amp;from=mal
  使用 vbs 从剪贴板中抓取一个 URL,然后在浏览器中打开网站
  问题:您好,ScriptingGuy!如何从剪贴板中获取 URL 并在浏览器中打开网站?--CL 回答:你好,CL。这是一个非常有趣的问题,或者应该说,这是两个非常有趣的问题。因为你实际上问了两个问题。第一个问题很简单:我可以用脚本打开一个特定的网站吗?你可能已经知道答案了,我可以大声回答你,是的!下面是一个示例脚本,它将“脚本中心”的 URL 存储在名为 strURL 的变量中。然后,此脚本创建 WSHShell 对象的实例并使用 Run

java爬虫抓取动态网页(伪造网页浏览器证书伪造不到数据数据的解决方案)

网站优化优采云 发表了文章 • 0 个评论 • 49 次浏览 • 2021-12-17 06:16 • 来自相关话题

  java爬虫抓取动态网页(伪造网页浏览器证书伪造不到数据数据的解决方案)
  这个java爬虫程序,在保证可以正常爬取网站的同时,增加了证书伪造,是针对网站反爬取无法抓取数据的解决方案。使用java ArrayList()抓取网站中的有效链接,同时释放资源,以免占用过多系统资源导致系统无法运行和终止。经过测试,确实可以用。
  首先是伪造网页浏览器证书,取得网站的信任,才能顺利抓取数据。具体方案如下:
  public static void getCertificate(){
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
try {
trustAllHttpsCertificates();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
  使用的代码片段太长,已经封装成函数,如下图:
  private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
}
  上述程序中使用的miTM函数如下:
  static class miTM implements javax.net.ssl.TrustManager,javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
}
  好了,到了这里,获取证书的代码就结束了。
  下一步是获取网页静态页面内容的功能:
  public static String returnHtml(String string){
URL url = null;
try {
url= new URL(string);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
URLConnection connection = null;
try {
connection = url.openConnection();
}catch (IOException e1) {
e1.printStackTrace();
}
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
try {
connection.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
InputStreamReader isr = null;
try {
isr=new InputStreamReader(connection.getInputStream(),Charset.forName("UTF-8"));
}catch (IOException e1) {
e1.printStackTrace();
}
// 定义一个字符串用来存储网页内容
String result = "";
// 定义一个缓冲字符输入流
BufferedReader in = null;
// 初始化 BufferedReader输入流来读取URL的响应
in = new BufferedReader(isr);
// 用来临时存储抓取到的每一行的数据
String line;
try {
while ((line = in.readLine()) != null) {
// 遍历抓取到的每一行并将其存储到result里面
result += line;
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
return result;
}
  仅仅获取网页的静态资源是不够的。我们还需要抓取页面上的链接并进行迭代访问以获得我们最终想要的数据:
  public static void getLink(String result){
Document doc = Jsoup.parse(result);
Elements table = doc.select("table.resulttable");
Elements es=table.select("a");
for (Iterator it = es.iterator(); it.hasNext();) {
Element e = (Element) it.next();
link.add(e.attr("href"));
System.out.println(e.text()+" "+e.attr("href"));
}
}
  如果一些网站安全方面比较好,页面的数据会被Ajax动态加载。在这种情况下,我们需要通过ajax后台访问接口获取数据,然后进行链接拼接,然后直接访问后台数据接口获取json数据。具体方案如下:
<p>public static void getJson(ArrayList link){
FileOutputStream out=null;
try{
out = new FileOutputStream(new File("C:\\Users\\yihong\\Desktop\\数据抓取.txt"),true);
}catch(FileNotFoundException e){
}
String s;
for(int i=0;i 查看全部

  java爬虫抓取动态网页(伪造网页浏览器证书伪造不到数据数据的解决方案)
  这个java爬虫程序,在保证可以正常爬取网站的同时,增加了证书伪造,是针对网站反爬取无法抓取数据的解决方案。使用java ArrayList()抓取网站中的有效链接,同时释放资源,以免占用过多系统资源导致系统无法运行和终止。经过测试,确实可以用。
  首先是伪造网页浏览器证书,取得网站的信任,才能顺利抓取数据。具体方案如下:
  public static void getCertificate(){
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
try {
trustAllHttpsCertificates();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
  使用的代码片段太长,已经封装成函数,如下图:
  private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
}
  上述程序中使用的miTM函数如下:
  static class miTM implements javax.net.ssl.TrustManager,javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
}
  好了,到了这里,获取证书的代码就结束了。
  下一步是获取网页静态页面内容的功能:
  public static String returnHtml(String string){
URL url = null;
try {
url= new URL(string);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
URLConnection connection = null;
try {
connection = url.openConnection();
}catch (IOException e1) {
e1.printStackTrace();
}
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
try {
connection.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
InputStreamReader isr = null;
try {
isr=new InputStreamReader(connection.getInputStream(),Charset.forName("UTF-8"));
}catch (IOException e1) {
e1.printStackTrace();
}
// 定义一个字符串用来存储网页内容
String result = "";
// 定义一个缓冲字符输入流
BufferedReader in = null;
// 初始化 BufferedReader输入流来读取URL的响应
in = new BufferedReader(isr);
// 用来临时存储抓取到的每一行的数据
String line;
try {
while ((line = in.readLine()) != null) {
// 遍历抓取到的每一行并将其存储到result里面
result += line;
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
return result;
}
  仅仅获取网页的静态资源是不够的。我们还需要抓取页面上的链接并进行迭代访问以获得我们最终想要的数据:
  public static void getLink(String result){
Document doc = Jsoup.parse(result);
Elements table = doc.select("table.resulttable");
Elements es=table.select("a");
for (Iterator it = es.iterator(); it.hasNext();) {
Element e = (Element) it.next();
link.add(e.attr("href"));
System.out.println(e.text()+" "+e.attr("href"));
}
}
  如果一些网站安全方面比较好,页面的数据会被Ajax动态加载。在这种情况下,我们需要通过ajax后台访问接口获取数据,然后进行链接拼接,然后直接访问后台数据接口获取json数据。具体方案如下:
<p>public static void getJson(ArrayList link){
FileOutputStream out=null;
try{
out = new FileOutputStream(new File("C:\\Users\\yihong\\Desktop\\数据抓取.txt"),true);
}catch(FileNotFoundException e){
}
String s;
for(int i=0;i

java爬虫抓取动态网页(Web网络爬虫系统的原理及应用)

网站优化优采云 发表了文章 • 0 个评论 • 64 次浏览 • 2021-12-17 01:29 • 来自相关话题

  java爬虫抓取动态网页(Web网络爬虫系统的原理及应用)
  1、 爬虫技术概述
  网络爬虫是按照一定的规则自动抓取万维网上信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,可以自动将采集它所能访问的页面的所有内容获取或更新这些网站@的内容和检索方法&gt;. 从功能上来说,爬虫一般分为三部分:数据采集、处理、存储。传统爬虫从一个或多个初始网页的网址开始,获取初始网页上的网址。在爬取网页的过程中,他们不断地从当前页面中提取新的URL并将它们放入队列中,直到满足系统的某个停止条件。聚焦爬虫的工作流程比较复杂。需要按照一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
  (1) 爬取目标的描述或定义;
  (2) 对网页或数据的分析和过滤;
  (3) URL 搜索策略。
  
  2、爬取的原理
  2.1 网络爬虫原理
  网络爬虫系统的作用是下载网页数据,为搜索引擎系统提供数据源。许多大型互联网搜索引擎系统被称为基于Web数据的搜索引擎系统,如谷歌和百度。这说明了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文本信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程就像一个爬虫或蜘蛛在网络上漫游,所以被称为网络爬虫系统或网络蜘蛛系统,英文称为Spider或Crawler。
  
  2.2 网络爬虫系统的工作原理
  在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页并处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等内容。爬虫的基本工作由解析器完成。资源库用于存储下载的网页资源,一般使用Oracle数据库等大型数据库存储,并建立索引。
  控制器
  控制器是网络爬虫的中央控制器。主要负责根据系统传递过来的URL链接分配一个线程,然后启动线程调用爬虫对网页进行爬取。
  解析器
  解析器是负责网络爬虫的主要部分。它的主要任务包括:下载网页,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
  资源库
  主要用于存储网页中下载的数据记录,并提供生成索引的目标源。中大型数据库产品包括:Oracle、Sql Server等。
  网络爬虫系统一般会选择一些输出度(网页中超链接的数量)较高的比较重要的URL作为种子URL集合。网络爬虫系统使用这些种子集作为初始 URL 开始数据爬取。由于网页收录链接信息,因此可以通过现有网页的网址获取一些新的网址。网页之间的指向结构可以看作是一个森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能会导致爬虫系统陷入网站内部,不利于在靠近网站首页的网页上搜索信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。
  
  网络爬虫的基本工作流程如下:
  1.先选择一部分精心挑选的种子网址;
  2.将这些URL放入URL队列中进行抓取;
  3. 从待爬取的URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页并保存到下载的网页库中。另外,将这些网址放入已爬取的网址队列中。
  4.对爬取的URL队列中的URL进行分析,分析其中的其他URL,将这些URL放入待爬取的URL队列中,从而进入下一个循环。
  
  
  2.3 爬取策略
  在爬虫系统中,要爬取的URL队列是一个非常重要的部分。URL队列中要爬取的URL按什么顺序排列也是一个很重要的问题,因为它涉及到先爬哪个页面,后爬哪个页面。确定这些 URL 顺序的方法称为抓取策略。下面重点介绍几种常见的爬取策略:
  2.3.1 深度优先遍历策略
  深度优先遍历策略是指网络爬虫会从起始页开始,逐个跟踪每一个链接,处理完这一行后转移到下一个起始页,继续跟踪链接。我们以下图为例:
  遍历的路径:AFG EHI BCD
  
  2.3.2 广度优先遍历策略
  广度优先遍历策略的基本思想是将新下载的网页中找到的链接直接插入到待爬取的URL队列的末尾。即网络爬虫会先抓取起始网页中所有链接的网页,然后选择其中一个链接的网页,继续抓取该网页中链接的所有网页。以上图为例:
  遍历路径:ABCDEF GHI
  2.3.3 反向链接计数策略
  反向链接数是指从其他网页链接到某个网页的数量。反向链接的数量表示网页内容被他人推荐的程度。因此,很多时候搜索引擎的爬取系统都会使用这个指标来评估网页的重要性,从而决定不同网页的爬取顺序。
  在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量不能完全坐等别人的重视。因此,搜索引擎通常会考虑一些可靠的反向链接。
  2.3.4Partial PageRank 策略
  Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,连同要爬取的URL队列中的URL,组成一个网页集,计算每个页面的PageRank值,经过计算完成后,将要爬取的URL队列中的URL按照PageRank值的大小进行排列,依次爬取页面。
  如果每个页面都被抓取,则重新计算 PageRank 值。一个折衷的方案是:每爬取K个页面后,重新计算PageRank值。但是,这种情况下仍然存在一个问题:对于已经从下载页面中分析出来的链接,也就是我们前面提到的未知网页部分,暂时没有PageRank值。为了解决这个问题,这些页面会被赋予一个临时的PageRank值:将所有传入该页面链中的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排名。以下示例说明:
  2.3.5OPIC 策略
  该算法实际上对页面的重要性进行评分。在算法开始之前,给所有页面相同的初始现金(cash)。下载某个页面P后,将P的现金分配给所有从P解析的链接,清空P的现金。待抓取的 URL 队列中的所有页面均按照现金的数量进行排序。
  2.3.六大站优先策略
  URL队列中所有要爬取的网页,按照所属的网站进行分类。网站需要下载的页面较多,优先下载。这种策略因此被称为大站优先策略。
  3、 爬虫分类
  我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫基本上可以分为三类:
  (1)分布式爬虫:Nutch
  (2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
  (3)非JAVA爬虫:scrapy(基于Python语言开发)
  3.1 个分布式爬虫
  爬虫采用分布式,主要解决两个问题:
  1)海量网址管理
  2)网速
  最流行的分布式爬虫是 Apache 的 Nutch。但是对于大多数用户来说,Nutch 是这些类型的爬虫中最糟糕的选择,原因如下:
  1)Nutch 是一款专为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的一组进程中有三分之二是为搜索引擎设计的。精细提取没有多大意义。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发,让Nutch适合精炼业务,你基本上会破坏Nutch的框架,将Nutch改得面目全非,并有能力修改Nutch。自己写一个新的确实更好。分布式爬虫框架。
  2)Nutch 依赖于hadoop 来运行,而hadoop 本身也消耗了大量的时间。如果集群机器数量少,爬取速度不如单机爬虫快。
  3) 虽然Nutch有一套插件机制,但也被宣传为一个亮点。可以看到一些开源的Nutch插件,提供精细的提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多烂。使用反射机制加载和调用插件使得编写和调试程序变得极其困难,更不用说在其上开发复杂的精细提取系统了。并且Nutch没有提供相应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点是为搜索引擎服务的,不提供精细提取的挂载点。Nutch的大部分精提取插件都挂载在挂载点“解析器”(parser)上,
  4)使用Nutch进行爬虫的二次开发,爬虫的准备和调试所需的时间往往是单机爬虫的十倍以上。学习Nutch源代码的成本非常高,更何况一个团队中的每个人都必须了解Nutch源代码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
  5) 很多人说Nutch2有gora,可以持久化数据到avro文件、hbase、mysql等,其实很多人理解错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。这不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
  6)Nutch2的版本目前不适合开发。Nutch官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果你想和nutch一起使用hbase(大多数人使用nutch2只是为了使用hbase),你只能在0.90版本左右使用hbase,因此你必须将hadoop版本减少到hadoop 0.2或所以。而且,Nutch2的官方教程更具有误导性。Nutch2有两个教程,分别是Nutch1.x和Nutch2.x。Nutch2.x 官网可以支持转到hbase 0.94。但其实这个Nutch2.x指的是Nutch2.3之前和Nutch2.2.1之后的版本。此版本在官方SVN中不断更新。
  所以,如果你不是搜索引擎,尽量不要选择Nutch作为爬虫。有些团队喜欢效仿。他们之所以坚持选择Nutch开发集约化提取的爬虫,其实是因为Nutch的名气(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目被推迟。
  如果你是一个搜索引擎,Nutch1.x 是一个非常好的选择。Nutch1.x 与 solr 或 es 合作组成了一个非常强大的搜索引擎。如果非要使用Nutch2,建议等到Nutch2.3发布。当前的 Nutch2 是一个非常不稳定的版本。
  
  分布式爬虫平台架构图
  3.2 JAVA爬虫
  这里将JAVA爬虫单独划分为一个类别,因为JAVA在网络爬虫的生态系统中是非常完备的。相关资料也是最全的。这里可能有争议,我只是随便说说。
  其实,开源网络爬虫(框架)的开发很简单,难点复杂的问题(比如DOM树解析定位、字符集检测、海量URL去重)都已经被前人解决了,可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历机器上的文件以查找文件中的信息。没有任何困难。之所以选择开源爬虫框架,是为了省事。比如爬虫URL管理、线程池等模块任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
  用于爬虫的功能。用户比较关心的问题往往是:
  1) 爬虫是否支持多线程,爬虫能不能用agent,能不能抓取重复数据,能不能抓取JS生成的信息?
  那些不支持多线程、代理、过滤重复URL的不叫开源爬虫,叫循环执行http请求。
  js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理页面。所以一种策略是利用这些爬虫来遍历网站,当遇到需要解析的页面时,将页面的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
  2)爬虫可以爬取ajax信息吗?
  网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax http请求,自己生成ajax请求的url,获取返回的数据。如果您自己生成 Ajax 请求,那么使用开源爬虫有什么意义呢?其实还是需要用到开源爬虫的线程池和URL管理功能(比如断点爬取)。
  如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来抓取这些请求?
  爬虫通常被设计成广度遍历或深度遍历的模式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历网站。第一轮爬取是爬取种子集(seeds)中的所有URL。简单的说,就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫遍历这些深度为1的种子(默认为广度遍历)。
  3)爬虫如何爬取网站登录?
  这些开源爬虫都支持在爬取时指定cookies,模拟登录主要是基于cookies。至于如何获取cookie,就不是爬虫的事情了。您可以手动获取cookies,也可以模拟http请求登录,也可以使用模拟浏览器自动登录获取cookies。
  4)爬虫如何从网页中提取信息?
  开源爬虫一般都集成了网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,这里就不评价了。
  5)爬虫是如何保存网页信息的?
  一些爬虫带有一个负责持久化的模块。例如,webmagic 有一个叫做管道的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等中,也有一些爬虫不直接为用户提供数据持久化模块。如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于使用pipeline模块好不好,类似于是否使用ORM来操作数据库的问题,看你的业务了。
  6)爬虫被网站屏蔽了,怎么办?
  爬虫已经被网站拦截了,通常可以通过多个代理(随机代理)解决。但是,这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,自己编写代码来随机获取代理(从数组中)。
  7)网页可以调用爬虫吗?
  爬虫的调用是在Web的服务器端调用的,你可以照常使用。这些爬虫都可以使用。
  8)爬行速度怎么样?
  一个单机的开源爬虫的速度基本可以用到机器网速的极限。爬虫速度慢,往往是因为用户线程少,网速慢,或者持久化数据时与数据库交互速度慢。而这些东西往往是由用户的机器和二次开发代码决定的。这些开源爬虫的速度非常好。
  9)显然代码写对了,爬不出来数据。是不是爬虫有问题?别的爬虫能解决吗?
  如果代码写对了,数据爬不出来,其他爬虫也是一样。在这种情况下,要么 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。无法通过更换爬虫来解决抓取数据失败的问题。
  10)哪个爬虫可以判断网站是否爬完了,哪个爬虫可以根据主题爬取?
  爬虫无法判断网站是否已经爬过,只能尽量覆盖。
  至于基于主题的爬取,爬虫只有向下爬取内容才知道主题是什么。所以它通常是从整体上爬下来,然后去过滤内容。如果觉得抓取过于笼统,可以通过限制网址规律等方法缩小范围。
  11) 哪个爬虫有更好的设计模式和结构?
  设计模式纯属无稽之谈。当软件设计模式好的时候,开发软件,然后总结出几种设计模式。设计模式对软件开发没有指导作用。使用设计模式来设计爬虫只会让爬虫的设计更加臃肿。
  在架构上,开源爬虫目前主要是详细数据结构的设计,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,不谈结构。
  所以对于JAVA开源爬虫,我想,找一个好用的就好了。如果业务复杂,使用哪种爬虫就必须经过复杂的二次开发才能满足需求。
  3.3 个非 Java 爬虫
  在非JAVA语言编写的爬虫中,有很多优秀的爬虫。这里提取为一个类别,不是为了爬虫本身的质量,而是为了larbin、scrapy等爬虫对开发成本的影响。
  先说python爬虫,python可以用30行代码完成JAVA 50行代码的任务。Python 代码编写确实很快,但是在调试代码阶段,Python 代码的调试往往比编码阶段节省的时间消耗的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务不复杂,使用scrapy也是相当不错的,可以轻松完成爬取任务。
  
  上图是Scrapy的架构图。绿线是数据流。首先,从初始 URL 开始,Scheduler 将其交给 Downloader 进行下载。下载完成后,会交给Spider进行分析。需要保存的数据会被发送到Item Pipeline。,即对数据进行后处理。此外,可以在数据流通道中安装各种中间件来进行必要的处理。所以在开发爬虫的时候,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
  对于C++爬虫来说,学习成本会比较大。而且你不能只计算一个人的学习成本。如果软件需要团队开发或交接,那将是很多人的学习成本。软件调试并不是那么容易。
  还有一些ruby、php爬虫,这里不多评论。确实有一些非常小的数据采集任务,用ruby或者php非常方便。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能会产生一些你找不到的bug(人少用少)信息)
  4、反爬虫技术
  由于搜索引擎的流行,网络爬虫已经成为一种非常流行的网络技术。除了专门从事搜索的谷歌、雅虎、微软和百度,几乎每个大型门户网站网站都有自己大大小小的搜索引擎。可以叫出的名字有几十个,不知道的名字也有上万个。对于一个内容驱动的网站来说,难免会被网络爬虫光顾。
  网站上一些智能搜索引擎爬虫的爬取频率比较合理,消耗的资源比较少。但是,很多不良的网络爬虫对网页的爬取能力较差,经常会发送几十甚至上百个请求,重复爬取循环。拿,这种爬虫往往对中小网站是毁灭性的打击,尤其是缺乏爬虫编写经验的程序员写的爬虫,破坏力极强,网站的访问压力会非常大。, 会导致网站 访问缓慢甚至无法访问。
  一般来说,网站从三个方面进行反爬虫:用户请求的Headers、用户行为、网站目录和数据加载方式。前两个比较容易遇到,从这些角度来看,大多数网站都是反爬虫。将采用第三类ajax应用网站,增加爬虫难度。
  4.1 个通过 Headers 的反爬虫
  从用户请求的Headers反爬取是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(部分资源网站的防盗就是检测Referer)。如果遇到这种反爬虫机制,可以直接给爬虫添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者修改Referer值为目标网站域名【注:经常容易被Ignore,通过对请求的抓包分析确定referer,将其添加到模拟访问的请求头中该程序]。对于检测header的反爬虫,在爬虫中修改或添加header很容易绕过。
  4.2 基于用户行为的反爬虫
  网站的另一部分是检测用户行为,比如在短时间内从同一个IP多次访问同一个页面,或者在短时间内在同一个账号内多次执行相同的操作. 【这种反爬需要足够的ip来应对】
  大部分网站都是前一种情况。在这种情况下,使用IP代理可以解决。可以专门写一个爬虫来爬取网上公开的代理ip,检测后全部保存。这类代理ip爬虫经常用到,最好自己准备一个。代理IP数量较多后,可以每隔几次请求换一个IP。这在requests或urllib2中很容易做到,这样你就可以轻松绕过第一个反爬虫。【点评:动态拨号也是一种解决方案】
  在第二种情况下,您可以在每次请求后以几秒钟的随机间隔发出下一个请求。一些存在逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求来绕过同一账号不能在短时间内多次发出相同请求的限制。【评论:账号的反爬限制一般很难处理,几秒的随机请求也可能被屏蔽。如果有多个账号,在它们之间切换会有更好的效果】
  4.3 动态页面反爬虫
  以上情况大部分出现在静态页面上,还有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。首先使用Firebug或者HttpFox来分析网络请求【点评:感觉google和IE的网络请求分析也很好】。如果能找到ajax请求,分析出响应的具体参数和具体含义,就可以通过上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
  能够直接模拟ajax请求获取数据是很棒的,但是有的网站加密了ajax请求的所有参数。我们没有办法为我们需要的数据构造一个请求。这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,对接口参数进行加密。遇到这样的网站,就不能用上面的方法了。我使用selenium+phantomJS框架,调用浏览器内核,使用phantomJS执行js模拟人的操作,触发页面中的js脚本。从填表到点击按钮再到滚动页面,一切都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。【评论:支持phantomJS】
  使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面是在一定程度上通过添加Headers来冒充浏览器),它是浏览器本身,phantomJS是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别point-and-touch(12306)或滑动验证码,页面表单的暴力破解等)。它还将在自动化渗透方面大显身手,未来也会如此。提这个。 查看全部

  java爬虫抓取动态网页(Web网络爬虫系统的原理及应用)
  1、 爬虫技术概述
  网络爬虫是按照一定的规则自动抓取万维网上信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,可以自动将采集它所能访问的页面的所有内容获取或更新这些网站@的内容和检索方法&gt;. 从功能上来说,爬虫一般分为三部分:数据采集、处理、存储。传统爬虫从一个或多个初始网页的网址开始,获取初始网页上的网址。在爬取网页的过程中,他们不断地从当前页面中提取新的URL并将它们放入队列中,直到满足系统的某个停止条件。聚焦爬虫的工作流程比较复杂。需要按照一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
  (1) 爬取目标的描述或定义;
  (2) 对网页或数据的分析和过滤;
  (3) URL 搜索策略。
  
  2、爬取的原理
  2.1 网络爬虫原理
  网络爬虫系统的作用是下载网页数据,为搜索引擎系统提供数据源。许多大型互联网搜索引擎系统被称为基于Web数据的搜索引擎系统,如谷歌和百度。这说明了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文本信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程就像一个爬虫或蜘蛛在网络上漫游,所以被称为网络爬虫系统或网络蜘蛛系统,英文称为Spider或Crawler。
  
  2.2 网络爬虫系统的工作原理
  在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页并处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等内容。爬虫的基本工作由解析器完成。资源库用于存储下载的网页资源,一般使用Oracle数据库等大型数据库存储,并建立索引。
  控制器
  控制器是网络爬虫的中央控制器。主要负责根据系统传递过来的URL链接分配一个线程,然后启动线程调用爬虫对网页进行爬取。
  解析器
  解析器是负责网络爬虫的主要部分。它的主要任务包括:下载网页,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
  资源库
  主要用于存储网页中下载的数据记录,并提供生成索引的目标源。中大型数据库产品包括:Oracle、Sql Server等。
  网络爬虫系统一般会选择一些输出度(网页中超链接的数量)较高的比较重要的URL作为种子URL集合。网络爬虫系统使用这些种子集作为初始 URL 开始数据爬取。由于网页收录链接信息,因此可以通过现有网页的网址获取一些新的网址。网页之间的指向结构可以看作是一个森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能会导致爬虫系统陷入网站内部,不利于在靠近网站首页的网页上搜索信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。
  
  网络爬虫的基本工作流程如下:
  1.先选择一部分精心挑选的种子网址;
  2.将这些URL放入URL队列中进行抓取;
  3. 从待爬取的URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页并保存到下载的网页库中。另外,将这些网址放入已爬取的网址队列中。
  4.对爬取的URL队列中的URL进行分析,分析其中的其他URL,将这些URL放入待爬取的URL队列中,从而进入下一个循环。
  
  
  2.3 爬取策略
  在爬虫系统中,要爬取的URL队列是一个非常重要的部分。URL队列中要爬取的URL按什么顺序排列也是一个很重要的问题,因为它涉及到先爬哪个页面,后爬哪个页面。确定这些 URL 顺序的方法称为抓取策略。下面重点介绍几种常见的爬取策略:
  2.3.1 深度优先遍历策略
  深度优先遍历策略是指网络爬虫会从起始页开始,逐个跟踪每一个链接,处理完这一行后转移到下一个起始页,继续跟踪链接。我们以下图为例:
  遍历的路径:AFG EHI BCD
  
  2.3.2 广度优先遍历策略
  广度优先遍历策略的基本思想是将新下载的网页中找到的链接直接插入到待爬取的URL队列的末尾。即网络爬虫会先抓取起始网页中所有链接的网页,然后选择其中一个链接的网页,继续抓取该网页中链接的所有网页。以上图为例:
  遍历路径:ABCDEF GHI
  2.3.3 反向链接计数策略
  反向链接数是指从其他网页链接到某个网页的数量。反向链接的数量表示网页内容被他人推荐的程度。因此,很多时候搜索引擎的爬取系统都会使用这个指标来评估网页的重要性,从而决定不同网页的爬取顺序。
  在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量不能完全坐等别人的重视。因此,搜索引擎通常会考虑一些可靠的反向链接。
  2.3.4Partial PageRank 策略
  Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,连同要爬取的URL队列中的URL,组成一个网页集,计算每个页面的PageRank值,经过计算完成后,将要爬取的URL队列中的URL按照PageRank值的大小进行排列,依次爬取页面。
  如果每个页面都被抓取,则重新计算 PageRank 值。一个折衷的方案是:每爬取K个页面后,重新计算PageRank值。但是,这种情况下仍然存在一个问题:对于已经从下载页面中分析出来的链接,也就是我们前面提到的未知网页部分,暂时没有PageRank值。为了解决这个问题,这些页面会被赋予一个临时的PageRank值:将所有传入该页面链中的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排名。以下示例说明:
  2.3.5OPIC 策略
  该算法实际上对页面的重要性进行评分。在算法开始之前,给所有页面相同的初始现金(cash)。下载某个页面P后,将P的现金分配给所有从P解析的链接,清空P的现金。待抓取的 URL 队列中的所有页面均按照现金的数量进行排序。
  2.3.六大站优先策略
  URL队列中所有要爬取的网页,按照所属的网站进行分类。网站需要下载的页面较多,优先下载。这种策略因此被称为大站优先策略。
  3、 爬虫分类
  我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫基本上可以分为三类:
  (1)分布式爬虫:Nutch
  (2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
  (3)非JAVA爬虫:scrapy(基于Python语言开发)
  3.1 个分布式爬虫
  爬虫采用分布式,主要解决两个问题:
  1)海量网址管理
  2)网速
  最流行的分布式爬虫是 Apache 的 Nutch。但是对于大多数用户来说,Nutch 是这些类型的爬虫中最糟糕的选择,原因如下:
  1)Nutch 是一款专为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的一组进程中有三分之二是为搜索引擎设计的。精细提取没有多大意义。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发,让Nutch适合精炼业务,你基本上会破坏Nutch的框架,将Nutch改得面目全非,并有能力修改Nutch。自己写一个新的确实更好。分布式爬虫框架。
  2)Nutch 依赖于hadoop 来运行,而hadoop 本身也消耗了大量的时间。如果集群机器数量少,爬取速度不如单机爬虫快。
  3) 虽然Nutch有一套插件机制,但也被宣传为一个亮点。可以看到一些开源的Nutch插件,提供精细的提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多烂。使用反射机制加载和调用插件使得编写和调试程序变得极其困难,更不用说在其上开发复杂的精细提取系统了。并且Nutch没有提供相应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点是为搜索引擎服务的,不提供精细提取的挂载点。Nutch的大部分精提取插件都挂载在挂载点“解析器”(parser)上,
  4)使用Nutch进行爬虫的二次开发,爬虫的准备和调试所需的时间往往是单机爬虫的十倍以上。学习Nutch源代码的成本非常高,更何况一个团队中的每个人都必须了解Nutch源代码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
  5) 很多人说Nutch2有gora,可以持久化数据到avro文件、hbase、mysql等,其实很多人理解错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。这不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
  6)Nutch2的版本目前不适合开发。Nutch官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果你想和nutch一起使用hbase(大多数人使用nutch2只是为了使用hbase),你只能在0.90版本左右使用hbase,因此你必须将hadoop版本减少到hadoop 0.2或所以。而且,Nutch2的官方教程更具有误导性。Nutch2有两个教程,分别是Nutch1.x和Nutch2.x。Nutch2.x 官网可以支持转到hbase 0.94。但其实这个Nutch2.x指的是Nutch2.3之前和Nutch2.2.1之后的版本。此版本在官方SVN中不断更新。
  所以,如果你不是搜索引擎,尽量不要选择Nutch作为爬虫。有些团队喜欢效仿。他们之所以坚持选择Nutch开发集约化提取的爬虫,其实是因为Nutch的名气(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目被推迟。
  如果你是一个搜索引擎,Nutch1.x 是一个非常好的选择。Nutch1.x 与 solr 或 es 合作组成了一个非常强大的搜索引擎。如果非要使用Nutch2,建议等到Nutch2.3发布。当前的 Nutch2 是一个非常不稳定的版本。
  
  分布式爬虫平台架构图
  3.2 JAVA爬虫
  这里将JAVA爬虫单独划分为一个类别,因为JAVA在网络爬虫的生态系统中是非常完备的。相关资料也是最全的。这里可能有争议,我只是随便说说。
  其实,开源网络爬虫(框架)的开发很简单,难点复杂的问题(比如DOM树解析定位、字符集检测、海量URL去重)都已经被前人解决了,可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历机器上的文件以查找文件中的信息。没有任何困难。之所以选择开源爬虫框架,是为了省事。比如爬虫URL管理、线程池等模块任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
  用于爬虫的功能。用户比较关心的问题往往是:
  1) 爬虫是否支持多线程,爬虫能不能用agent,能不能抓取重复数据,能不能抓取JS生成的信息?
  那些不支持多线程、代理、过滤重复URL的不叫开源爬虫,叫循环执行http请求。
  js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理页面。所以一种策略是利用这些爬虫来遍历网站,当遇到需要解析的页面时,将页面的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
  2)爬虫可以爬取ajax信息吗?
  网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax http请求,自己生成ajax请求的url,获取返回的数据。如果您自己生成 Ajax 请求,那么使用开源爬虫有什么意义呢?其实还是需要用到开源爬虫的线程池和URL管理功能(比如断点爬取)。
  如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来抓取这些请求?
  爬虫通常被设计成广度遍历或深度遍历的模式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历网站。第一轮爬取是爬取种子集(seeds)中的所有URL。简单的说,就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫遍历这些深度为1的种子(默认为广度遍历)。
  3)爬虫如何爬取网站登录?
  这些开源爬虫都支持在爬取时指定cookies,模拟登录主要是基于cookies。至于如何获取cookie,就不是爬虫的事情了。您可以手动获取cookies,也可以模拟http请求登录,也可以使用模拟浏览器自动登录获取cookies。
  4)爬虫如何从网页中提取信息?
  开源爬虫一般都集成了网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,这里就不评价了。
  5)爬虫是如何保存网页信息的?
  一些爬虫带有一个负责持久化的模块。例如,webmagic 有一个叫做管道的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等中,也有一些爬虫不直接为用户提供数据持久化模块。如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于使用pipeline模块好不好,类似于是否使用ORM来操作数据库的问题,看你的业务了。
  6)爬虫被网站屏蔽了,怎么办?
  爬虫已经被网站拦截了,通常可以通过多个代理(随机代理)解决。但是,这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,自己编写代码来随机获取代理(从数组中)。
  7)网页可以调用爬虫吗?
  爬虫的调用是在Web的服务器端调用的,你可以照常使用。这些爬虫都可以使用。
  8)爬行速度怎么样?
  一个单机的开源爬虫的速度基本可以用到机器网速的极限。爬虫速度慢,往往是因为用户线程少,网速慢,或者持久化数据时与数据库交互速度慢。而这些东西往往是由用户的机器和二次开发代码决定的。这些开源爬虫的速度非常好。
  9)显然代码写对了,爬不出来数据。是不是爬虫有问题?别的爬虫能解决吗?
  如果代码写对了,数据爬不出来,其他爬虫也是一样。在这种情况下,要么 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。无法通过更换爬虫来解决抓取数据失败的问题。
  10)哪个爬虫可以判断网站是否爬完了,哪个爬虫可以根据主题爬取?
  爬虫无法判断网站是否已经爬过,只能尽量覆盖。
  至于基于主题的爬取,爬虫只有向下爬取内容才知道主题是什么。所以它通常是从整体上爬下来,然后去过滤内容。如果觉得抓取过于笼统,可以通过限制网址规律等方法缩小范围。
  11) 哪个爬虫有更好的设计模式和结构?
  设计模式纯属无稽之谈。当软件设计模式好的时候,开发软件,然后总结出几种设计模式。设计模式对软件开发没有指导作用。使用设计模式来设计爬虫只会让爬虫的设计更加臃肿。
  在架构上,开源爬虫目前主要是详细数据结构的设计,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,不谈结构。
  所以对于JAVA开源爬虫,我想,找一个好用的就好了。如果业务复杂,使用哪种爬虫就必须经过复杂的二次开发才能满足需求。
  3.3 个非 Java 爬虫
  在非JAVA语言编写的爬虫中,有很多优秀的爬虫。这里提取为一个类别,不是为了爬虫本身的质量,而是为了larbin、scrapy等爬虫对开发成本的影响。
  先说python爬虫,python可以用30行代码完成JAVA 50行代码的任务。Python 代码编写确实很快,但是在调试代码阶段,Python 代码的调试往往比编码阶段节省的时间消耗的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务不复杂,使用scrapy也是相当不错的,可以轻松完成爬取任务。
  
  上图是Scrapy的架构图。绿线是数据流。首先,从初始 URL 开始,Scheduler 将其交给 Downloader 进行下载。下载完成后,会交给Spider进行分析。需要保存的数据会被发送到Item Pipeline。,即对数据进行后处理。此外,可以在数据流通道中安装各种中间件来进行必要的处理。所以在开发爬虫的时候,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
  对于C++爬虫来说,学习成本会比较大。而且你不能只计算一个人的学习成本。如果软件需要团队开发或交接,那将是很多人的学习成本。软件调试并不是那么容易。
  还有一些ruby、php爬虫,这里不多评论。确实有一些非常小的数据采集任务,用ruby或者php非常方便。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能会产生一些你找不到的bug(人少用少)信息)
  4、反爬虫技术
  由于搜索引擎的流行,网络爬虫已经成为一种非常流行的网络技术。除了专门从事搜索的谷歌、雅虎、微软和百度,几乎每个大型门户网站网站都有自己大大小小的搜索引擎。可以叫出的名字有几十个,不知道的名字也有上万个。对于一个内容驱动的网站来说,难免会被网络爬虫光顾。
  网站上一些智能搜索引擎爬虫的爬取频率比较合理,消耗的资源比较少。但是,很多不良的网络爬虫对网页的爬取能力较差,经常会发送几十甚至上百个请求,重复爬取循环。拿,这种爬虫往往对中小网站是毁灭性的打击,尤其是缺乏爬虫编写经验的程序员写的爬虫,破坏力极强,网站的访问压力会非常大。, 会导致网站 访问缓慢甚至无法访问。
  一般来说,网站从三个方面进行反爬虫:用户请求的Headers、用户行为、网站目录和数据加载方式。前两个比较容易遇到,从这些角度来看,大多数网站都是反爬虫。将采用第三类ajax应用网站,增加爬虫难度。
  4.1 个通过 Headers 的反爬虫
  从用户请求的Headers反爬取是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(部分资源网站的防盗就是检测Referer)。如果遇到这种反爬虫机制,可以直接给爬虫添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者修改Referer值为目标网站域名【注:经常容易被Ignore,通过对请求的抓包分析确定referer,将其添加到模拟访问的请求头中该程序]。对于检测header的反爬虫,在爬虫中修改或添加header很容易绕过。
  4.2 基于用户行为的反爬虫
  网站的另一部分是检测用户行为,比如在短时间内从同一个IP多次访问同一个页面,或者在短时间内在同一个账号内多次执行相同的操作. 【这种反爬需要足够的ip来应对】
  大部分网站都是前一种情况。在这种情况下,使用IP代理可以解决。可以专门写一个爬虫来爬取网上公开的代理ip,检测后全部保存。这类代理ip爬虫经常用到,最好自己准备一个。代理IP数量较多后,可以每隔几次请求换一个IP。这在requests或urllib2中很容易做到,这样你就可以轻松绕过第一个反爬虫。【点评:动态拨号也是一种解决方案】
  在第二种情况下,您可以在每次请求后以几秒钟的随机间隔发出下一个请求。一些存在逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求来绕过同一账号不能在短时间内多次发出相同请求的限制。【评论:账号的反爬限制一般很难处理,几秒的随机请求也可能被屏蔽。如果有多个账号,在它们之间切换会有更好的效果】
  4.3 动态页面反爬虫
  以上情况大部分出现在静态页面上,还有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。首先使用Firebug或者HttpFox来分析网络请求【点评:感觉google和IE的网络请求分析也很好】。如果能找到ajax请求,分析出响应的具体参数和具体含义,就可以通过上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
  能够直接模拟ajax请求获取数据是很棒的,但是有的网站加密了ajax请求的所有参数。我们没有办法为我们需要的数据构造一个请求。这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,对接口参数进行加密。遇到这样的网站,就不能用上面的方法了。我使用selenium+phantomJS框架,调用浏览器内核,使用phantomJS执行js模拟人的操作,触发页面中的js脚本。从填表到点击按钮再到滚动页面,一切都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。【评论:支持phantomJS】
  使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面是在一定程度上通过添加Headers来冒充浏览器),它是浏览器本身,phantomJS是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别point-and-touch(12306)或滑动验证码,页面表单的暴力破解等)。它还将在自动化渗透方面大显身手,未来也会如此。提这个。

java爬虫抓取动态网页(java爬虫抓取动态网页需要一个java框架(一))

网站优化优采云 发表了文章 • 0 个评论 • 49 次浏览 • 2021-12-14 14:06 • 来自相关话题

  java爬虫抓取动态网页(java爬虫抓取动态网页需要一个java框架(一))
  java爬虫抓取动态网页需要一个java爬虫框架,而想要有很好的收敛性的话,需要知道很多java基础知识点,经过前期一段时间的学习,在这里就要大佬提供下找一下看看新的网页代码中是否隐藏着一些我们需要的东西。1:常用数据结构hashmap//每个元素存放了key值,当存放的数据量较少时,可以使用1的内存即可,以实现小量元素处理。
  hashmap,扩容随机生成。hashtable、concurrenthashmap、concurrentskiplistmap2:常用算法冒泡排序:以桶来分组或以循环节循环遍历,使得子节点上增加最快最大的数。堆排序:多空间排序、尽可能以最快的数据更新最小的数,数据可能会存在扩展性与吞吐量方面的问题,可用结构化思维对待java里这部分定义性分析。
  归并排序:结构化编程中分解成多个小的分区再求和合并。平衡二叉树:在任意一个节点上存放相同数量的元素的,树每次增加一个,每个节点的层数,不能超过当前个数,否则的话发生递归出现空闲记录的概率较大。二叉树高度log2n(n-。
  1),
  1)。
  选择排序:按logn(n-
  1)次方遍历所有节点的方法。动态规划:迭代算法、贪心算法等。3:常用集合枚举,set(集合),fole(列表,queue)java中的集合可以说是按照元素的种类来划分:listlist代表列表;列表中的元素需要通过[位置]来标记,列表元素之间也存在关系,是一种容器,有长度可以是3或者更多;collectionablelist是聚合(incomplete)的存储结构,arry-collection是一个集合,它将arraylist的collection等同于原子操作。
  list的使用arraylist和vector不能使用objectstring来传递这两个java中的列表类型的值;list的生命周期list代表列表,它既可以是一个数组也可以是一个链表。list的方法注意的问题分配空间和迭代方法使用列表引用方法一般就是直接size方法实现在底层,其他方法在初始化阶段都是和arraylist不一样的方法。
<p>size方法提供的是给元素的长度。streamlinearstream是一种模拟一次分组操作过程,因为它可以像数组操作一样直接操作数组元素。inorderfilter是使用了sort()方法的for循环for循环是list类的核心方法之一。for(inti=0;i 查看全部

  java爬虫抓取动态网页(java爬虫抓取动态网页需要一个java框架(一))
  java爬虫抓取动态网页需要一个java爬虫框架,而想要有很好的收敛性的话,需要知道很多java基础知识点,经过前期一段时间的学习,在这里就要大佬提供下找一下看看新的网页代码中是否隐藏着一些我们需要的东西。1:常用数据结构hashmap//每个元素存放了key值,当存放的数据量较少时,可以使用1的内存即可,以实现小量元素处理。
  hashmap,扩容随机生成。hashtable、concurrenthashmap、concurrentskiplistmap2:常用算法冒泡排序:以桶来分组或以循环节循环遍历,使得子节点上增加最快最大的数。堆排序:多空间排序、尽可能以最快的数据更新最小的数,数据可能会存在扩展性与吞吐量方面的问题,可用结构化思维对待java里这部分定义性分析。
  归并排序:结构化编程中分解成多个小的分区再求和合并。平衡二叉树:在任意一个节点上存放相同数量的元素的,树每次增加一个,每个节点的层数,不能超过当前个数,否则的话发生递归出现空闲记录的概率较大。二叉树高度log2n(n-。
  1),
  1)。
  选择排序:按logn(n-
  1)次方遍历所有节点的方法。动态规划:迭代算法、贪心算法等。3:常用集合枚举,set(集合),fole(列表,queue)java中的集合可以说是按照元素的种类来划分:listlist代表列表;列表中的元素需要通过[位置]来标记,列表元素之间也存在关系,是一种容器,有长度可以是3或者更多;collectionablelist是聚合(incomplete)的存储结构,arry-collection是一个集合,它将arraylist的collection等同于原子操作。
  list的使用arraylist和vector不能使用objectstring来传递这两个java中的列表类型的值;list的生命周期list代表列表,它既可以是一个数组也可以是一个链表。list的方法注意的问题分配空间和迭代方法使用列表引用方法一般就是直接size方法实现在底层,其他方法在初始化阶段都是和arraylist不一样的方法。
<p>size方法提供的是给元素的长度。streamlinearstream是一种模拟一次分组操作过程,因为它可以像数组操作一样直接操作数组元素。inorderfilter是使用了sort()方法的for循环for循环是list类的核心方法之一。for(inti=0;i

java爬虫抓取动态网页(PHP解析器和PHP相比较,python适合做爬虫吗?)

网站优化优采云 发表了文章 • 0 个评论 • 35 次浏览 • 2021-12-12 17:16 • 来自相关话题

  java爬虫抓取动态网页(PHP解析器和PHP相比较,python适合做爬虫吗?)
  对比python和PHP,python适合爬取。原因如下
  抓取网页本身的界面
  与java、c#、C++、python等其他静态编程语言相比,抓取网页文档的界面更加简洁;相对于其他动态脚本语言,如 perl、shell、python,urllib2 包提供了更完整的 Web 文档 API 访问。(当然红宝石也是不错的选择)
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这就是我们需要模拟用户代理的行为来构造合适的请求的地方,比如模拟用户登录,模拟会话/cookie存储和设置。python中有优秀的第三方包帮你搞定,比如Requests,mechanize
  爬行后处理
  抓取到的网页通常需要进行处理,如过滤html标签、提取文本等。Python的beautifulsoap提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。
  其实很多语言和工具都可以做到以上功能,但是python可以做到最快最干净。人生苦短,你需要python。
  py对linux来说功能很强大,语言也很简单。
  NO.1 快速开发(唯一能比python开发效率更高的语言是rudy) 语言简洁,没有那么多技巧,所以非常清晰易读。
  NO.2 跨平台(由于python开源,比java更能体现“一次编写,到处运行”
  NO.3 解释(无需直接编译、运行/调试代码)
  NO.4 架构选择太多(主要的GUI架构包括wxPython、tkInter、PyGtk、PyQt。
  PHP脚本主要用于以下三个方面:
  服务器端脚本。这是PHP最传统也是最主要的目标领域。要进行这项工作,需要具备以下三点:PHP解析器(CGI或服务器模块)、web
  服务器和网络浏览器。运行web服务器时需要安装配置PHP,然后可以使用web浏览器访问PHP程序的输出,即浏览服务
  PHP 页面在最后。如果您只是在尝试 PHP 编程,那么所有这些都可以在您的家用计算机上运行。有关更多信息,请参阅安装章节。命令行脚本。
  您可以编写一个 PHP 脚本,并且不需要任何服务器或浏览器来运行它。这样,只需要PHP解析器就可以执行。这种用法是
  是 cron(Unix 或 Linux 环境)或 Task Scheduler(Windows 环境)日常运行脚本的理想选择。这些脚本也可用于处理
  管理简单的文本。有关更多信息,请参阅 PHP 的命令行模式。编写桌面应用程序。对于具有图形界面的桌面应用程序,PHP 可能不会
  最好的语言之一,但是如果用户非常精通PHP并且想在客户端应用程序中使用PHP的一些高级功能,他们可以使用PHP-GTK来编写这个
  这些程序。这样,您也可以编写跨平台的应用程序。PHP-GTK 是 PHP 的一个扩展,通常发布的 PHP 包中不收录它。
  网友的观点扩大了:
  之前用PHP Node.js Python写了一个爬虫脚本,简单说一下。
  首先是PHP。先说优点:网上大量的爬取解析html框架,各种工具都可以直接使用,比较省心。缺点:首先,速度/效率是个问题。有一次下载电影海报的时候,因为crontab定时执行,没有优化,打开的php进程太多,直接导致内存爆了。然后语法也很拖沓。关键词太多,不够简洁。给人一种没有经过精心设计的感觉,写起来很麻烦。
  节点.js。优点是效率,效率还是效率。因为网络是异步的,所以基本上和并发数百个进程一样强大。内存和CPU使用量非常小。如果对捕获的数据没有进行复杂的计算和处理,那么系统就会成为瓶颈。基本上就是写入 MySQL 和其他数据库的带宽和 I/O 速度。当然,优点的反面也是缺点。异步网络意味着您需要回调。这时候,如果业务需求是线性的,比如必须等待上一页被爬取到数据,下一页才能被爬取,甚至更多。层依赖,会有可怕的多层回调!基本上这个时候代码结构和逻辑就会乱了。当然,
  最后,让我们谈谈Python。如果你对效率没有极端的要求,那么推荐Python!首先,Python 的语法非常简洁,同一个句子可以少打很多次。那么,Python非常适合数据处理,比如函数参数的打包和解包,列表分析,矩阵处理,非常方便。
  至此,这篇关于python和php的更适合写爬虫的文章介绍到这里。更多适合爬取内容的php和python相关内容,请在面圈教程中搜索之前的文章或者继续浏览下面的相关文章,希望大家多多支持面圈教程将来! 查看全部

  java爬虫抓取动态网页(PHP解析器和PHP相比较,python适合做爬虫吗?)
  对比python和PHP,python适合爬取。原因如下
  抓取网页本身的界面
  与java、c#、C++、python等其他静态编程语言相比,抓取网页文档的界面更加简洁;相对于其他动态脚本语言,如 perl、shell、python,urllib2 包提供了更完整的 Web 文档 API 访问。(当然红宝石也是不错的选择)
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这就是我们需要模拟用户代理的行为来构造合适的请求的地方,比如模拟用户登录,模拟会话/cookie存储和设置。python中有优秀的第三方包帮你搞定,比如Requests,mechanize
  爬行后处理
  抓取到的网页通常需要进行处理,如过滤html标签、提取文本等。Python的beautifulsoap提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。
  其实很多语言和工具都可以做到以上功能,但是python可以做到最快最干净。人生苦短,你需要python。
  py对linux来说功能很强大,语言也很简单。
  NO.1 快速开发(唯一能比python开发效率更高的语言是rudy) 语言简洁,没有那么多技巧,所以非常清晰易读。
  NO.2 跨平台(由于python开源,比java更能体现“一次编写,到处运行”
  NO.3 解释(无需直接编译、运行/调试代码)
  NO.4 架构选择太多(主要的GUI架构包括wxPython、tkInter、PyGtk、PyQt。
  PHP脚本主要用于以下三个方面:
  服务器端脚本。这是PHP最传统也是最主要的目标领域。要进行这项工作,需要具备以下三点:PHP解析器(CGI或服务器模块)、web
  服务器和网络浏览器。运行web服务器时需要安装配置PHP,然后可以使用web浏览器访问PHP程序的输出,即浏览服务
  PHP 页面在最后。如果您只是在尝试 PHP 编程,那么所有这些都可以在您的家用计算机上运行。有关更多信息,请参阅安装章节。命令行脚本。
  您可以编写一个 PHP 脚本,并且不需要任何服务器或浏览器来运行它。这样,只需要PHP解析器就可以执行。这种用法是
  是 cron(Unix 或 Linux 环境)或 Task Scheduler(Windows 环境)日常运行脚本的理想选择。这些脚本也可用于处理
  管理简单的文本。有关更多信息,请参阅 PHP 的命令行模式。编写桌面应用程序。对于具有图形界面的桌面应用程序,PHP 可能不会
  最好的语言之一,但是如果用户非常精通PHP并且想在客户端应用程序中使用PHP的一些高级功能,他们可以使用PHP-GTK来编写这个
  这些程序。这样,您也可以编写跨平台的应用程序。PHP-GTK 是 PHP 的一个扩展,通常发布的 PHP 包中不收录它。
  网友的观点扩大了:
  之前用PHP Node.js Python写了一个爬虫脚本,简单说一下。
  首先是PHP。先说优点:网上大量的爬取解析html框架,各种工具都可以直接使用,比较省心。缺点:首先,速度/效率是个问题。有一次下载电影海报的时候,因为crontab定时执行,没有优化,打开的php进程太多,直接导致内存爆了。然后语法也很拖沓。关键词太多,不够简洁。给人一种没有经过精心设计的感觉,写起来很麻烦。
  节点.js。优点是效率,效率还是效率。因为网络是异步的,所以基本上和并发数百个进程一样强大。内存和CPU使用量非常小。如果对捕获的数据没有进行复杂的计算和处理,那么系统就会成为瓶颈。基本上就是写入 MySQL 和其他数据库的带宽和 I/O 速度。当然,优点的反面也是缺点。异步网络意味着您需要回调。这时候,如果业务需求是线性的,比如必须等待上一页被爬取到数据,下一页才能被爬取,甚至更多。层依赖,会有可怕的多层回调!基本上这个时候代码结构和逻辑就会乱了。当然,
  最后,让我们谈谈Python。如果你对效率没有极端的要求,那么推荐Python!首先,Python 的语法非常简洁,同一个句子可以少打很多次。那么,Python非常适合数据处理,比如函数参数的打包和解包,列表分析,矩阵处理,非常方便。
  至此,这篇关于python和php的更适合写爬虫的文章介绍到这里。更多适合爬取内容的php和python相关内容,请在面圈教程中搜索之前的文章或者继续浏览下面的相关文章,希望大家多多支持面圈教程将来!

java爬虫抓取动态网页(所说的问题试试)

网站优化优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-11 02:25 • 来自相关话题

  java爬虫抓取动态网页(所说的问题试试)
  是的,最后还是用Selenium来实现上一篇我提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果还是可以接受的。
  继续昨天的话题,既然要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的第一选择是 htmlunit。先简单介绍一下htmlunit。以下段落摘自互联网。
  htmlunit 是一个开源的java 页面分析工具。启动 htmlunit 后,将在底部启动一个无界面浏览器。用户可以指定浏览器类型:firefox、ie等,如果不指定,默认使用INTERNET_EXPLORER_7:
  WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
  通过一个简单的调用:
  HtmlPage 页面 = webClient.getPage(url);
  可以得到页面的HtmlPage表示,然后通过:
  InputStream 是 = targetPage.getWebResponse().getContentAsStream()
  可以获取页面的输入流,进而获取页面的源代码,这对于网络爬虫项目非常有用。
  当然,你也可以从页面中获取更多的页面元素。
  很重要的一点是 HtmlUnit 提供了对执行 javascript 的支持:
  page.executeJavaScript(javascript)
  js执行后返回一个ScriptResult对象,通过该对象可以获取js执行后的页面等信息。默认情况下,内部浏览器执行js后,会做一次页面跳转,跳转到执行js后生成的新页面。如果js执行失败,页面跳转将不会被执行。
  最后可以通过获取 page.executeJavaScript(javascript).getNewPage() 来获取执行后的页面。换句话说,这里需要人工执行JavaScript。显然这不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻页面的时候总是出错。我还没有找到错误在哪里。分析网上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数的顺序或编码问题,请求失败并报错。关键是我运行后没有得到我需要的结果。
  然后我寻找了另一种解决方案。这时候我找到了SeleniumWebDriver,这就是我需要的解决方案。
  参考资料和例子后,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn");
11 list.add("http://www.sohu.com");
12 list.add("http://www.163.com");
13 list.add("http://www.qq.com");
14
15 long start,end;
16
17 for(int i=0;i 查看全部

  java爬虫抓取动态网页(所说的问题试试)
  是的,最后还是用Selenium来实现上一篇我提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果还是可以接受的。
  继续昨天的话题,既然要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的第一选择是 htmlunit。先简单介绍一下htmlunit。以下段落摘自互联网。
  htmlunit 是一个开源的java 页面分析工具。启动 htmlunit 后,将在底部启动一个无界面浏览器。用户可以指定浏览器类型:firefox、ie等,如果不指定,默认使用INTERNET_EXPLORER_7:
  WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
  通过一个简单的调用:
  HtmlPage 页面 = webClient.getPage(url);
  可以得到页面的HtmlPage表示,然后通过:
  InputStream 是 = targetPage.getWebResponse().getContentAsStream()
  可以获取页面的输入流,进而获取页面的源代码,这对于网络爬虫项目非常有用。
  当然,你也可以从页面中获取更多的页面元素。
  很重要的一点是 HtmlUnit 提供了对执行 javascript 的支持:
  page.executeJavaScript(javascript)
  js执行后返回一个ScriptResult对象,通过该对象可以获取js执行后的页面等信息。默认情况下,内部浏览器执行js后,会做一次页面跳转,跳转到执行js后生成的新页面。如果js执行失败,页面跳转将不会被执行。
  最后可以通过获取 page.executeJavaScript(javascript).getNewPage() 来获取执行后的页面。换句话说,这里需要人工执行JavaScript。显然这不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻页面的时候总是出错。我还没有找到错误在哪里。分析网上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数的顺序或编码问题,请求失败并报错。关键是我运行后没有得到我需要的结果。
  然后我寻找了另一种解决方案。这时候我找到了SeleniumWebDriver,这就是我需要的解决方案。
  参考资料和例子后,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064";);
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn";);
11 list.add("http://www.sohu.com";);
12 list.add("http://www.163.com";);
13 list.add("http://www.qq.com";);
14
15 long start,end;
16
17 for(int i=0;i

java爬虫抓取动态网页(为什么大多数人喜欢用Python呢?答案是这样的!)

网站优化优采云 发表了文章 • 0 个评论 • 68 次浏览 • 2021-12-10 19:06 • 来自相关话题

  java爬虫抓取动态网页(为什么大多数人喜欢用Python呢?答案是这样的!)
  内容
  爬虫一定要使用Python吗?
  你可以使用Java,或者C。编程语言只是工具。抓取数据是目的。
  您可以使用任何工具来实现您的目标。就像吃饭一样,你可以用叉子或筷子。最终的结果是你可以吃。那么为什么大多数人喜欢使用Python呢?答:因为 Python 编写爬虫很容易。不明白?问:为什么吃米饭不用刀叉?用筷子吗?因为这很容易!使用方便!
  在众多编程语言中,Python 上手最快,语法最简单。更重要的是,有很多第三方支持库可供爬虫使用。
  爬行动物的矛和盾
  防爬机构
  门户 网站。可以制定相应的策略或技术手段,防止爬虫爬取网站数据。
  防反爬策略
  爬虫程序可以通过制定相关策略或技术手段破解门户网站中的反爬虫机制,从而获取门户网站中的相关数据。
  软件:
  jupyter 笔记本
  蟒蛇3.8
  pycharm
  安装python注意配置环境变量:
  Python环境变量的配置-知乎()
  
  你可以参考上面的
  在cmd上输入python
  
  如果你弹出商店页面:
  
  只需将python路径调整到路径上的第一个位置即可。
  入门案例:
  显示百度页面:
  from urllib.request import urlopen
url = "http://www.baidu.com"
resp = urlopen(url)
# print(resp.read().decode("utf-8"))#转换为解码
with open("mybaidu.html", mode="w") as f:
f.write(resp.read().decode("utf-8"))
print("over!")
  生成的文件可以在浏览器中打开,就是百度的页面。 查看全部

  java爬虫抓取动态网页(为什么大多数人喜欢用Python呢?答案是这样的!)
  内容
  爬虫一定要使用Python吗?
  你可以使用Java,或者C。编程语言只是工具。抓取数据是目的。
  您可以使用任何工具来实现您的目标。就像吃饭一样,你可以用叉子或筷子。最终的结果是你可以吃。那么为什么大多数人喜欢使用Python呢?答:因为 Python 编写爬虫很容易。不明白?问:为什么吃米饭不用刀叉?用筷子吗?因为这很容易!使用方便!
  在众多编程语言中,Python 上手最快,语法最简单。更重要的是,有很多第三方支持库可供爬虫使用。
  爬行动物的矛和盾
  防爬机构
  门户 网站。可以制定相应的策略或技术手段,防止爬虫爬取网站数据。
  防反爬策略
  爬虫程序可以通过制定相关策略或技术手段破解门户网站中的反爬虫机制,从而获取门户网站中的相关数据。
  软件:
  jupyter 笔记本
  蟒蛇3.8
  pycharm
  安装python注意配置环境变量:
  Python环境变量的配置-知乎()
  
  你可以参考上面的
  在cmd上输入python
  
  如果你弹出商店页面:
  
  只需将python路径调整到路径上的第一个位置即可。
  入门案例:
  显示百度页面:
  from urllib.request import urlopen
url = "http://www.baidu.com"
resp = urlopen(url)
# print(resp.read().decode("utf-8"))#转换为解码
with open("mybaidu.html", mode="w") as f:
f.write(resp.read().decode("utf-8"))
print("over!")
  生成的文件可以在浏览器中打开,就是百度的页面。

java爬虫抓取动态网页( wpfgaoerfu:wpfgaoerfu如何从动态加载网页抓取数据(图))

网站优化优采云 发表了文章 • 0 个评论 • 30 次浏览 • 2021-12-10 14:16 • 来自相关话题

  java爬虫抓取动态网页(
wpfgaoerfu:wpfgaoerfu如何从动态加载网页抓取数据(图))
  python爬虫从动态加载的网页中抓取数据
  2020年4月13日第14读 来源:wpfgaoerfu
  如何从动态加载的网页中抓取数据1、获取请求的网页打开网址:如#/?tab=%E5%85%A8%E9%83%A8 那么如何从该网页加载数据, 点击F12查看
  
  
  2、请求数据,我们看到请求数据是根据page_size获取的,这样我们就可以模拟Request请求,获取数据请看下面的代码
  import requests
# 1.分析网站真是请求地址---抓包分析
def get_json(url):
# 伪装 程序伪装成浏览器
headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'}
params = {
'page_size' : 10,
'next_offset': str(num), # 不断变化
'tag': '今日热门',
'platform': 'pc'
}
# url = 'https://api.vc.bilibili.com/board/v1/ranking/top?' # 找到真实请求地址
html = requests.get(url,params=params, headers=headers)
# print(html)
return html.json()
# 抓取大量数据 大量地址
# 1 11 21 31 41 :递增10 一个真实请求地址:包含10个视频
if __name__ == '__main__': # 可写可不写
for i in range(10):
url = 'https://api.vc.bilibili.com/board/v1/ranking/top?'
num = i * 10 + 1 # num == offset
html = get_json(url)
# 2.解析数据
infos = html['data']['items']
# print(infos)#list 列表[] ()tuple元祖 {}dict字典
for info in infos:
title = info['item']['description']
vedio_url = info['item']['video_playurl']
print(title, vedio_url)
  运行结果如下:
  获取每个视频地址,点击打开下载或观看
  
  以上就是从动态网页中抓取数据的整个过程的简单实现
  欢迎交流学习。 查看全部

  java爬虫抓取动态网页(
wpfgaoerfu:wpfgaoerfu如何从动态加载网页抓取数据(图))
  python爬虫从动态加载的网页中抓取数据
  2020年4月13日第14读 来源:wpfgaoerfu
  如何从动态加载的网页中抓取数据1、获取请求的网页打开网址:如#/?tab=%E5%85%A8%E9%83%A8 那么如何从该网页加载数据, 点击F12查看
  
  
  2、请求数据,我们看到请求数据是根据page_size获取的,这样我们就可以模拟Request请求,获取数据请看下面的代码
  import requests
# 1.分析网站真是请求地址---抓包分析
def get_json(url):
# 伪装 程序伪装成浏览器
headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'}
params = {
'page_size' : 10,
'next_offset': str(num), # 不断变化
'tag': '今日热门',
'platform': 'pc'
}
# url = 'https://api.vc.bilibili.com/board/v1/ranking/top?' # 找到真实请求地址
html = requests.get(url,params=params, headers=headers)
# print(html)
return html.json()
# 抓取大量数据 大量地址
# 1 11 21 31 41 :递增10 一个真实请求地址:包含10个视频
if __name__ == '__main__': # 可写可不写
for i in range(10):
url = 'https://api.vc.bilibili.com/board/v1/ranking/top?'
num = i * 10 + 1 # num == offset
html = get_json(url)
# 2.解析数据
infos = html['data']['items']
# print(infos)#list 列表[] ()tuple元祖 {}dict字典
for info in infos:
title = info['item']['description']
vedio_url = info['item']['video_playurl']
print(title, vedio_url)
  运行结果如下:
  获取每个视频地址,点击打开下载或观看
  
  以上就是从动态网页中抓取数据的整个过程的简单实现
  欢迎交流学习。

java爬虫抓取动态网页(java网络爬虫基础入门的总结及解决方法)

网站优化优采云 发表了文章 • 0 个评论 • 39 次浏览 • 2021-12-08 19:18 • 来自相关话题

  java爬虫抓取动态网页(java网络爬虫基础入门的总结及解决方法)
  刚开始接触java爬虫,这里总结一下网上搜索的一些理论知识
  主要参考文章:Gitchat的java网络爬虫基础,好像是收费的,不贵,感觉内容对新手很友好。
  一、爬虫介绍
  网络爬虫是一种自动提取网页的程序。它从万维网上下载网页供搜索引擎使用,是搜索引擎的重要组成部分。
  传统爬虫:
  获取URL-》放入队列-》抓取网页,分析信息-》新增网址-》放入队列-》抓取网页,分析信息...-》满足一定条件时停止。
  专注于爬虫:
  根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后根据搜索策略从队列中选择下一个URL,重复...直到满足一定条件停止。另外,爬虫爬取的网页会被系统存储起来进行一定的分析、过滤、索引,以便后续的查询和还原。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个问题:
  爬网目标的描述或定义。网页或数据的分析和过滤。URL 的搜索策略。
  网络爬虫设计有很多领域。我们需要掌握基本的编程语言(最好是已经有成熟API的语言),了解HTTP协议,了解web服务器、数据库、前端知识、网络安全等……
  分类:
  根据系统结构和实现技术,大致可以分为以下几类:通用网络爬虫、聚焦网络爬虫、增量网络爬虫、深度网络爬虫等。
  通用网络爬虫:爬取对象从一些种子网址扩展到整个Web,主要是门户搜索引擎和大型Web服务商采集数据。
  专注于网络爬虫:也称为主网络爬虫,是指有选择地抓取与​​预定义主题相关的页面,比上述一般的爬虫更具体。
  Incremental web crawler:一种对下载的网页进行增量更新并且只抓取新生成或更改的页面的爬虫。它可以确保抓取的页面尽可能新。历史已经采集上一页不再重复采集。
  常见情况:论坛订单评论数据采集(评论数据仅是用户最近几天或几个月的采集评论)
  深网爬虫:是指大部分内容无法通过静态链接获取,而我们需要的大部分数据是网页动态链接生成的页面,即Deep Web信息。Deep Web 也是一个爬虫框架,这里暂时不赘述。
  网络爬虫的爬取策略
  深度优先搜索策略,广度优先搜索策略。 查看全部

  java爬虫抓取动态网页(java网络爬虫基础入门的总结及解决方法)
  刚开始接触java爬虫,这里总结一下网上搜索的一些理论知识
  主要参考文章:Gitchat的java网络爬虫基础,好像是收费的,不贵,感觉内容对新手很友好。
  一、爬虫介绍
  网络爬虫是一种自动提取网页的程序。它从万维网上下载网页供搜索引擎使用,是搜索引擎的重要组成部分。
  传统爬虫:
  获取URL-》放入队列-》抓取网页,分析信息-》新增网址-》放入队列-》抓取网页,分析信息...-》满足一定条件时停止。
  专注于爬虫:
  根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后根据搜索策略从队列中选择下一个URL,重复...直到满足一定条件停止。另外,爬虫爬取的网页会被系统存储起来进行一定的分析、过滤、索引,以便后续的查询和还原。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个问题:
  爬网目标的描述或定义。网页或数据的分析和过滤。URL 的搜索策略。
  网络爬虫设计有很多领域。我们需要掌握基本的编程语言(最好是已经有成熟API的语言),了解HTTP协议,了解web服务器、数据库、前端知识、网络安全等……
  分类:
  根据系统结构和实现技术,大致可以分为以下几类:通用网络爬虫、聚焦网络爬虫、增量网络爬虫、深度网络爬虫等。
  通用网络爬虫:爬取对象从一些种子网址扩展到整个Web,主要是门户搜索引擎和大型Web服务商采集数据。
  专注于网络爬虫:也称为主网络爬虫,是指有选择地抓取与​​预定义主题相关的页面,比上述一般的爬虫更具体。
  Incremental web crawler:一种对下载的网页进行增量更新并且只抓取新生成或更改的页面的爬虫。它可以确保抓取的页面尽可能新。历史已经采集上一页不再重复采集。
  常见情况:论坛订单评论数据采集(评论数据仅是用户最近几天或几个月的采集评论)
  深网爬虫:是指大部分内容无法通过静态链接获取,而我们需要的大部分数据是网页动态链接生成的页面,即Deep Web信息。Deep Web 也是一个爬虫框架,这里暂时不赘述。
  网络爬虫的爬取策略
  深度优先搜索策略,广度优先搜索策略。

java爬虫抓取动态网页(爬虫+基于接口的网络爬虫(爬虫爬虫)(组图))

网站优化优采云 发表了文章 • 0 个评论 • 46 次浏览 • 2021-12-08 19:12 • 来自相关话题

  java爬虫抓取动态网页(爬虫+基于接口的网络爬虫(爬虫爬虫)(组图))
  爬虫+基于接口的网络爬虫
  上一篇讲了【java爬虫】---爬虫+jsoup轻松爬取博客。这种方法有一个很大的局限性,就是只能通过jsoup爬虫爬取静态网页,所以只能爬取当前页面上的所有新闻。如果需要爬取一个网站的所有信息,就需要通过接口反复调整网站的接口,通过改变参数来爬取网站@的所有数据信息&gt;.
  本博客旨在抓取黄金财经新闻资讯,抓取网站自建站以来发布的所有新闻资讯。下面将分步说明。这里重点讲一下思路,最后提供完整的源码。
  第一步:找到界面
  如果要获取这个网站的所有新闻数据,第一步当然是获取接口,通过接口获取所有信息。
  F12--&gt;网络--&gt;全部,找到界面:
  这三个参数的说明:
  limit=23 表示每次调用接口返回23条数据。
  information_id=56630 表示下面返回的23条数据是通过大于56630或小于56630的ID指纹返回的。
  flag=down 表示向下翻页。这里指的是23条ID小于56630的数据。
  通过邮递员测试
  输入:(这里返回两条,这里id=0代表最新的两条数据)
  返回json数据格式:
  
  接口返回信息
  第二步:通过定时任务启动爬虫工作
  @Slf4j
@Component
public class SchedulePressTrigger {
@Autowired
private CrawlerJinSeLivePressService crawlerJinSeLivePressService;
/**
* 定时抓取金色财经的新闻
*/
@Scheduled(initialDelay = 1000, fixedRate = 600 * 1000)
public void doCrawlJinSeLivePress() {
// log.info("开始抓取金色财经新闻, time:" + new Date());
try {
crawlerJinSeLivePressService.start();
} catch (Exception e) {
// log.error("本次抓取金色财经新闻异常", e);
}
// log.info("结束抓取金色财经新闻, time:" + new Date());
}
}
  第三步:主要实现类
  /**
* 抓取金色财经快讯
* @author xub
* @since 2018/6/29
*/
@Slf4j
@Service
public class CrawlerJinSeLivePressServiceImpl extends AbstractCrawlLivePressService implements
CrawlerJinSeLivePressService {
//这个参数代表每一次请求获得多少个数据
private static final int PAGE_SIZE = 15;
//这个是真正翻页参数,每一次找id比它小的15个数据(有写接口是通过page=1,2来进行翻页所以比较好理解一点,其实它们性质一样)
private long bottomId;
//这个这里没有用到,但是如果有数据层,就需要用到,这里我只是把它答应到控制台
@Autowired
private LivePressService livePressService;



//定时任务运行这个方法,doTask没有被重写,所有运行父类的方法
@Override
public void start() {
try {
doTask(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT);
} catch (IOException e) {
// log.error("抓取金色财经新闻异常", e);
}
}
@Override
protected List crawlPage(int pageNum) throws IOException {
// 最多抓取100页,多抓取也没有特别大的意思。
if (pageNum >= 100) {
return Collections.emptyList();
}
// 格式化翻页参数(第一次bottomId为0,第二次就是这次爬到的最小bottomId值)
String requestUrl = String.format(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT, PAGE_SIZE, bottomId);
Response response = OkHttp.singleton().newCall(
new Request.Builder().url(requestUrl).addHeader("referer", CoinPressConsts.CHAIN_FOR_LIVE_URL).get().build())
.execute();
if (response.isRedirect()) {
// 如果请求发生了跳转,说明请求不是原来的地址了,返回空数据。
return Collections.emptyList();
}
//先获得json数据格式
String responseText = response.body().string();
//在通过工具类进行数据赋值
JinSePressResult jinSepressResult = JsonUtils.objectFromJson(responseText, JinSePressResult.class);
if (null == jinSepressResult) {
// 反序列化失败
System.out.println("抓取金色财经新闻列表反序列化异常");
return Collections.emptyList();
}
// 取金色财经最小的记录id,来进行翻页
bottomId = jinSepressResult.getBottomId();
//这个是谷歌提供了guava包里的工具类,Lists这个集合工具,对list集合操作做了些优化提升。
List pageListPresss = Lists.newArrayListWithExpectedSize(PAGE_SIZE);
for (JinSePressResult.DayData dayData : jinSepressResult.getList()) {
JinSePressData data = dayData.getExtra();
//新闻发布时间(时间戳格式)这里可以来判断只爬多久时间以内的新闻
long createTime = data.getPublishedAt() * 1000;
Long timemill=System.currentTimeMillis();
// if (System.currentTimeMillis() - createTime > CoinPressConsts.MAX_CRAWLER_TIME) {
// // 快讯过老了,放弃
// continue;
// }
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sd = sdf.format(new Date(createTime)); // 时间戳转换成时间
Date newsCreateTime=new Date();
try {
//获得新闻发布时间
newsCreateTime = sdf.parse(sd);
} catch (ParseException e) {
e.printStackTrace();
}
//具体文章页面路径(这里可以通过这个路径+jsoup就可以爬新闻正文所有信息了)
String href = data.getTopicUrl();
//新闻摘要
String summary = data.getSummary();
//新闻阅读数量
String pressreadcount = data.getReadNumber();
//新闻标题
String title = dayData.getTitle();
pageListPresss.add(new PageListPress(href,title, Integer.parseInt(pressreadcount),
newsCreateTime , summary));
}
return pageListPresss;
}
}
  AbstractCrawlLivePressService 类
   public abstract class AbstractCrawlLivePressService {
String url;
public void doTask(String url) throws IOException {
this.url = url;
int pageNum = 1;
//通过 while (true)会一直循环调取接口,直到数据为空或者时间过老跳出循环
while (true) {
List newsList = crawlPage(pageNum++);
// 抓取不到新的内容本次抓取结束
if (CollectionUtils.isEmpty(newsList)) {
break;
}
//这里并没有把数据放到数据库,而是直接从控制台输出
for (int i = newsList.size() - 1; i >= 0; i--) {
PageListPress pageListNews = newsList.get(i);
System.out.println(pageListNews.toString());

}
}
}
//这个由具体实现类实现
protected abstract List crawlPage(int pageNum) throws IOException;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class PageListPress {
//新闻详情页面url
private String href;
//新闻标题
private String title;
//新闻阅读数量
private int readCounts;
//新闻发布时间
private Date createTime;
//新闻摘要
private String summary;

}
}
  锦色印刷结果
  /**
*在创建对象的时候一定要分析好json格式的类型
*金色新闻的返回格式就是第一层有普通属性和一个list集合
*在list集合中又有普通属性和一个extra的对象。
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class JinSePressResult {
private int news;
private int count;
@JsonProperty("top_id")
private long topId;
@JsonProperty("bottom_id")
private long bottomId;
//list的名字也要和json数据的list名字一致,否则无用
private List list;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class DayData {
private String title;
//这里对象的属性名extra也要和json的extra名字一致
private JinSePressData extra;
@JsonProperty("topic_url")
private String topicUrl;
}
}
  这里有两点需要注意
  (1) 创建对象时,首先要弄清楚json格式类型是否收录对象中的集合,或者集合中是否有对象等。
  (2) 只能定义自己需要的属性字段。当无法匹配json的属性名但类型不一致时,比如上面改成Listextra,序列化就会失败,因为json的extra明明是一个Object,这里接受的确实是一个集合。关键是要属于
  性别名称相同,所以赋值时会报错,序列化失败。
  第四步:查看操作结果
  这只是截取了控制台输出的部分信息。这样就可以得到网站的所有新闻信息。同时我们已经获取到了具体新闻的URL,那么我们就可以通过JSOup获取到该新闻的所有具体信息了。(完美的)
  
  第五步:数据库去重思路
  因为你不可能每次爬取都直接把播放数据放到数据库中,所以必须比较新闻数据库是否已经存在,如果不存在就放到数据库中。思路如下:
  (1)添加一个唯一属性字段,可以标识数据库表中的新闻,例如jinse+bottomId构成唯一属性,或者新闻的具体页面路径URI构成唯一属性。
  (2)创建地图集合,通过URI查看数据库是否存在,如果存在,则不存在。
  (3)存储前,如果为false则通过map.get(URI),然后存储到数据库中。
  git 源代码
  首先说明一下,源码本身通过了Idea测试,这里使用的是lombok。你现在需要为idea或eclipse配置Lombok。
  源地址:
  想的太多,做的太少,中间的差距就是麻烦。如果您不想担心,请不要考虑或做更多。中校【9】 查看全部

  java爬虫抓取动态网页(爬虫+基于接口的网络爬虫(爬虫爬虫)(组图))
  爬虫+基于接口的网络爬虫
  上一篇讲了【java爬虫】---爬虫+jsoup轻松爬取博客。这种方法有一个很大的局限性,就是只能通过jsoup爬虫爬取静态网页,所以只能爬取当前页面上的所有新闻。如果需要爬取一个网站的所有信息,就需要通过接口反复调整网站的接口,通过改变参数来爬取网站@的所有数据信息&gt;.
  本博客旨在抓取黄金财经新闻资讯,抓取网站自建站以来发布的所有新闻资讯。下面将分步说明。这里重点讲一下思路,最后提供完整的源码。
  第一步:找到界面
  如果要获取这个网站的所有新闻数据,第一步当然是获取接口,通过接口获取所有信息。
  F12--&gt;网络--&gt;全部,找到界面:
  这三个参数的说明:
  limit=23 表示每次调用接口返回23条数据。
  information_id=56630 表示下面返回的23条数据是通过大于56630或小于56630的ID指纹返回的。
  flag=down 表示向下翻页。这里指的是23条ID小于56630的数据。
  通过邮递员测试
  输入:(这里返回两条,这里id=0代表最新的两条数据)
  返回json数据格式:
  
  接口返回信息
  第二步:通过定时任务启动爬虫工作
  @Slf4j
@Component
public class SchedulePressTrigger {
@Autowired
private CrawlerJinSeLivePressService crawlerJinSeLivePressService;
/**
* 定时抓取金色财经的新闻
*/
@Scheduled(initialDelay = 1000, fixedRate = 600 * 1000)
public void doCrawlJinSeLivePress() {
// log.info("开始抓取金色财经新闻, time:" + new Date());
try {
crawlerJinSeLivePressService.start();
} catch (Exception e) {
// log.error("本次抓取金色财经新闻异常", e);
}
// log.info("结束抓取金色财经新闻, time:" + new Date());
}
}
  第三步:主要实现类
  /**
* 抓取金色财经快讯
* @author xub
* @since 2018/6/29
*/
@Slf4j
@Service
public class CrawlerJinSeLivePressServiceImpl extends AbstractCrawlLivePressService implements
CrawlerJinSeLivePressService {
//这个参数代表每一次请求获得多少个数据
private static final int PAGE_SIZE = 15;
//这个是真正翻页参数,每一次找id比它小的15个数据(有写接口是通过page=1,2来进行翻页所以比较好理解一点,其实它们性质一样)
private long bottomId;
//这个这里没有用到,但是如果有数据层,就需要用到,这里我只是把它答应到控制台
@Autowired
private LivePressService livePressService;



//定时任务运行这个方法,doTask没有被重写,所有运行父类的方法
@Override
public void start() {
try {
doTask(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT);
} catch (IOException e) {
// log.error("抓取金色财经新闻异常", e);
}
}
@Override
protected List crawlPage(int pageNum) throws IOException {
// 最多抓取100页,多抓取也没有特别大的意思。
if (pageNum >= 100) {
return Collections.emptyList();
}
// 格式化翻页参数(第一次bottomId为0,第二次就是这次爬到的最小bottomId值)
String requestUrl = String.format(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT, PAGE_SIZE, bottomId);
Response response = OkHttp.singleton().newCall(
new Request.Builder().url(requestUrl).addHeader("referer", CoinPressConsts.CHAIN_FOR_LIVE_URL).get().build())
.execute();
if (response.isRedirect()) {
// 如果请求发生了跳转,说明请求不是原来的地址了,返回空数据。
return Collections.emptyList();
}
//先获得json数据格式
String responseText = response.body().string();
//在通过工具类进行数据赋值
JinSePressResult jinSepressResult = JsonUtils.objectFromJson(responseText, JinSePressResult.class);
if (null == jinSepressResult) {
// 反序列化失败
System.out.println("抓取金色财经新闻列表反序列化异常");
return Collections.emptyList();
}
// 取金色财经最小的记录id,来进行翻页
bottomId = jinSepressResult.getBottomId();
//这个是谷歌提供了guava包里的工具类,Lists这个集合工具,对list集合操作做了些优化提升。
List pageListPresss = Lists.newArrayListWithExpectedSize(PAGE_SIZE);
for (JinSePressResult.DayData dayData : jinSepressResult.getList()) {
JinSePressData data = dayData.getExtra();
//新闻发布时间(时间戳格式)这里可以来判断只爬多久时间以内的新闻
long createTime = data.getPublishedAt() * 1000;
Long timemill=System.currentTimeMillis();
// if (System.currentTimeMillis() - createTime > CoinPressConsts.MAX_CRAWLER_TIME) {
// // 快讯过老了,放弃
// continue;
// }
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sd = sdf.format(new Date(createTime)); // 时间戳转换成时间
Date newsCreateTime=new Date();
try {
//获得新闻发布时间
newsCreateTime = sdf.parse(sd);
} catch (ParseException e) {
e.printStackTrace();
}
//具体文章页面路径(这里可以通过这个路径+jsoup就可以爬新闻正文所有信息了)
String href = data.getTopicUrl();
//新闻摘要
String summary = data.getSummary();
//新闻阅读数量
String pressreadcount = data.getReadNumber();
//新闻标题
String title = dayData.getTitle();
pageListPresss.add(new PageListPress(href,title, Integer.parseInt(pressreadcount),
newsCreateTime , summary));
}
return pageListPresss;
}
}
  AbstractCrawlLivePressService 类
   public abstract class AbstractCrawlLivePressService {
String url;
public void doTask(String url) throws IOException {
this.url = url;
int pageNum = 1;
//通过 while (true)会一直循环调取接口,直到数据为空或者时间过老跳出循环
while (true) {
List newsList = crawlPage(pageNum++);
// 抓取不到新的内容本次抓取结束
if (CollectionUtils.isEmpty(newsList)) {
break;
}
//这里并没有把数据放到数据库,而是直接从控制台输出
for (int i = newsList.size() - 1; i >= 0; i--) {
PageListPress pageListNews = newsList.get(i);
System.out.println(pageListNews.toString());

}
}
}
//这个由具体实现类实现
protected abstract List crawlPage(int pageNum) throws IOException;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class PageListPress {
//新闻详情页面url
private String href;
//新闻标题
private String title;
//新闻阅读数量
private int readCounts;
//新闻发布时间
private Date createTime;
//新闻摘要
private String summary;

}
}
  锦色印刷结果
  /**
*在创建对象的时候一定要分析好json格式的类型
*金色新闻的返回格式就是第一层有普通属性和一个list集合
*在list集合中又有普通属性和一个extra的对象。
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class JinSePressResult {
private int news;
private int count;
@JsonProperty("top_id")
private long topId;
@JsonProperty("bottom_id")
private long bottomId;
//list的名字也要和json数据的list名字一致,否则无用
private List list;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class DayData {
private String title;
//这里对象的属性名extra也要和json的extra名字一致
private JinSePressData extra;
@JsonProperty("topic_url")
private String topicUrl;
}
}
  这里有两点需要注意
  (1) 创建对象时,首先要弄清楚json格式类型是否收录对象中的集合,或者集合中是否有对象等。
  (2) 只能定义自己需要的属性字段。当无法匹配json的属性名但类型不一致时,比如上面改成Listextra,序列化就会失败,因为json的extra明明是一个Object,这里接受的确实是一个集合。关键是要属于
  性别名称相同,所以赋值时会报错,序列化失败。
  第四步:查看操作结果
  这只是截取了控制台输出的部分信息。这样就可以得到网站的所有新闻信息。同时我们已经获取到了具体新闻的URL,那么我们就可以通过JSOup获取到该新闻的所有具体信息了。(完美的)
  
  第五步:数据库去重思路
  因为你不可能每次爬取都直接把播放数据放到数据库中,所以必须比较新闻数据库是否已经存在,如果不存在就放到数据库中。思路如下:
  (1)添加一个唯一属性字段,可以标识数据库表中的新闻,例如jinse+bottomId构成唯一属性,或者新闻的具体页面路径URI构成唯一属性。
  (2)创建地图集合,通过URI查看数据库是否存在,如果存在,则不存在。
  (3)存储前,如果为false则通过map.get(URI),然后存储到数据库中。
  git 源代码
  首先说明一下,源码本身通过了Idea测试,这里使用的是lombok。你现在需要为idea或eclipse配置Lombok。
  源地址:
  想的太多,做的太少,中间的差距就是麻烦。如果您不想担心,请不要考虑或做更多。中校【9】

java爬虫抓取动态网页(深入剖析Python爬虫框架的结构与运作流程的相关内容)

网站优化优采云 发表了文章 • 0 个评论 • 51 次浏览 • 2021-12-07 19:06 • 来自相关话题

  java爬虫抓取动态网页(深入剖析Python爬虫框架的结构与运作流程的相关内容)
  想了解深入解析Python爬虫框架Scrapy的结构和运行过程吗?在本文中,pluskid将为大家仔细讲解Scrapy框架的结构和运行过程以及一些代码示例。欢迎阅读指正,先重点说一下:Python、Scrapy、爬虫,一起学习。
  网络爬虫(Spider)是一种在互联网上爬行的机器人。当然,它通常不是实体机器人,因为网络本身也是一个虚拟的东西,所以这个“机器人”其实就是一个程序,不是爬行,而是有一定的用途,爬行的时候会采集. 一些信息。例如,谷歌有很多爬虫采集网页内容和它们之间的链接信息;另一个例子是别有用心的爬虫在互联网上采集诸如foo [at] bar [dot] com之类的东西。此外,还有一些定制的爬虫,专门针对某个网站。比如JavaEye的Robbin前段时间写了几篇专门对付恶意爬虫的博客。是的)和 网站 诸如小众软件或 LinuxToy 之类的软件通常会被整个站点抓取下来并以不同的名称挂出。其实,爬虫的基本原理非常简单。只要能上网,能分析网页,现在大多数语言都有方便的Http客户端库可以抓取网页,最简单的HTML分析可以直接使用正则规则。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。然而,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。
  爬虫的两部分是下载网页。需要考虑的问题有很多,比如如何最大限度地利用本地带宽,如何调度不同站点的web请求,以减少其他服务器的负担。在高性能的Web Crawler系统中,DNS查询也将成为亟待优化的瓶颈。此外,还有一些“配置文件”需要遵循(例如,robots.txt)。获取网页后的分析过程也很复杂。网上奇奇怪怪的东西很多,各种HTML页面出现各种错误。分析所有这些几乎是不可能的。另外,随着AJAX的普及,如何获取Javascript动态生成的内容成为了一个大问题;此外,互联网上有各种有意或无意出现的蜘蛛陷阱。如果一味的跟着超链接走,就会被困在陷阱里。比如,这个网站据说是谷歌之前宣布互联网上Unique URL的数量已经达到1万亿,所以这个人很自豪的宣布第二万亿。:D
  然而,实际上并没有多少人需要像谷歌这样的通用爬虫。通常我们构建一个爬虫来爬取一个特定的或者某个类型的网站,所谓知己知彼,百战不死,我们可以提前爬取对网站做一些分析网站 结构,事情变得容易多了。通过分析和选择有价值的链接进行跟踪,我们可以避免很多不必要的链接或蜘蛛陷阱。如果网站的结构允许选择合适的路径,我们就可以按照感兴趣的事物的一定顺序再次爬取它,这样就连URL重复的判断都可以省略了。
  比如我们要爬下pongba博客中的博客文字,通过观察,很容易发现我们对其中两个页面感兴趣:
  文章列表页面,比如首页,或者URL为/page/\d+/的页面,通过Firebug可以看到每个文章链接都在h1下的一个标签中(应该是注意Firebug的HTML面板看到的HTML代码可能和View Source看到的有些不同,如果网页中有动态修改DOM树的Javascript,前者是修改后的版本,Firebug正则化后,比如属性有引号等等,后者通常是你的蜘蛛爬取的原创内容,如果你用正则表达式分析页面或者使用的HTML Parser和Firefox有些不同,(需要特别注意). 另外,在一个类为 wp-pagenavi 的 div 中有指向不同列表页面的链接。
  文章 内容页,每个博客都有这样一个页面,比如/2008/09/11/machine-learning-and-ai-resources/,收录了文章的完整内容,这是我们的感受感兴趣的内容。
  因此,我们从首页开始,利用 wp-pagenavi 中的链接来获取其他 文章 列表页面。特别是我们定义了一个路径:只跟随Next Page的链接,这样我们就可以从头到尾依次进行一遍,省去了反复爬行判断的麻烦。另外,文章列表页上链接到具体文章的链接对应的页面就是我们真正要保存的数据页。
  这样,它实用的脚本语言写一个ad hoc爬虫来完成这个任务并不难,不过今天的主角是Scrapy,它是一个用Python编写的爬虫框架,简单轻量,非常方便,官网说已经在实际生产中使用过,所以不是玩具级别的东西。但是,目前还没有 Release 版本。您可以直接使用其 Mercurial 存储库中的源代码来安装它。不过这个东西也可以不安装直接使用,方便随时更新。文档很详细,不再赘述。
  Scrapy 使用异步网络库 Twisted 来处理网络通信。架构清晰,收录各种中间件接口,可以灵活满足各种需求。整体架构如下图所示:
  
  绿线是数据流向。从最初的URL开始,Scheduler将其交给Downloader进行下载,下载完成后交给Spider进行分析。Spider分析的结果有两种:一种是需要进一步爬取的链接。比如之前分析的“下一页”的链接,这些东西会被发回给Scheduler;另一个是需要保存的数据,发送到Item Pipeline,就是数据的后处理(详细分析、过滤、存储等)。此外,可以在数据流通道中安装各种中间件来进行必要的处理。
  具体内容将在上一个附件中介绍。
  它看起来很复杂,但使用起来非常简单。就像Rails一样,首先新建一个项目:
  
scrapy-admin.py startproject blog_crawl
  会创建一个blog_crawl目录,里面有一个scrapy-ctl.py是整个项目的控制脚本,代码全部放在子目录blog_crawl下。为了能够爬取,我们在spiders目录下新建一个mindhacks_spider.py,定义我们的Spider如下:
  
from scrapy.spider import BaseSpider

class MindhacksSpider(BaseSpider):
domain_name = "mindhacks.cn"
start_urls = ["http://mindhacks.cn/"]

def parse(self, response):
return []

SPIDER = MindhacksSpider()
  我们的MindhacksSpider继承自BaseSpider(通常直接来自scrapy.contrib.spiders.CrawlSpider,它更通用,更方便,但是为了展示数据是如何解析的,这里使用了BaseSpider),变量domain_name和start_urls是容易理解是什么意思,parse方法就是我们需要定义的回调函数。默认请求在得到响应后会调用这个回调函数。这里我们需要解析页面,返回两个结果(需要进一步爬取链接,需要保存Data)。让我觉得有点奇怪的是,它的接口定义中的两个结果居然混在一个列表中返回。我不知道为什么它是这样设计的。最后不是要把他们分开吗?总之,这里我们先写一个空函数,它只返回一个空列表。另外,定义一个“全局”变量 SPIDER,它会在 Scrapy 导入这个模块时被实例化,并且会被 Scrapy 引擎自动找到。所以你可以先运行爬虫试试:
  
./scrapy-ctl.py crawl mindhacks.cn
  会有一堆输出,可以看到爬取了,因为这是初始的URL,但是因为我们在parse函数中没有返回需要进一步爬取的URL,所以整个爬取过程只爬取了首页和结束了。下一步是分析页面。Scrapy 提供了一个非常方便的Shell(需要IPython),可以让我们做实验。使用以下命令启动 Shell:
  
./scrapy-ctl.py shell http://mindhacks.cn
  它会启动爬虫,抓取命令行指定的页面,然后进入shell。根据提示,我们有很多现成的变量可以使用。其中之一是 hxs,它是一个 HtmlXPathSelector。mindhacks 的 HTML 页面是比较标准的。直接用XPath分析非常方便。通过Firebug可以看到每个博客文章的链接都在h1下,所以在Shell中使用这个XPath表达式测试:
  
In [1]: hxs.x('//h1/a/@href').extract()
Out[1]:
[u'http://mindhacks.cn/2009/07/06/why-you-should-do-it-yourself/',
u'http://mindhacks.cn/2009/05/17/seven-years-in-nju/',
u'http://mindhacks.cn/2009/03/28/effective-learning-and-memorization/',
u'http://mindhacks.cn/2009/03/15/preconception-explained/',
u'http://mindhacks.cn/2009/03/09/first-principles-of-programming/',
u'http://mindhacks.cn/2009/02/15/why-you-should-start-blogging-now/',
u'http://mindhacks.cn/2009/02/09/writing-is-better-thinking/',
u'http://mindhacks.cn/2009/02/07/better-explained-conflicts-in-intimate-relationship/',
u'http://mindhacks.cn/2009/02/07/independence-day/',
u'http://mindhacks.cn/2009/01/18/escape-from-your-shawshank-part1/']
  这正是我们需要的 URL。另外可以找到“下一页”的链接,和其他几个页面的链接放在一个div里,但是“下一页”的链接没有title属性,所以写XPath
  
//div[@class="wp-pagenavi"]/a[not(@title)]
  但是,如果你往回翻一页,你会发现“上一页”其实是一样的,所以你需要确定链接上的文字是下一页的箭头u'\xbb',这可能有是用 XPath 编写的。去,不过好像这本身就是一个unicode转义字符,由于编码原因不清楚,直接在外面判断,最终解析函数如下:
  
def parse(self, response):
items = []
hxs = HtmlXPathSelector(response)
posts = hxs.x('//h1/a/@href').extract()
items.extend([self.make_requests_from_url(url).replace(callback=self.parse_post)
for url in posts])

page_links = hxs.x('//div[@class="wp-pagenavi"]/a[not(@title)]')
for link in page_links:
if link.x('text()').extract()[0] == u'\xbb':
url = link.x('@href').extract()[0]
items.append(self.make_requests_from_url(url))

return items
  前半部分是解析需要爬取的博客正文的链接,后半部分是给出“下一页”的链接。需要注意的是,这里返回的列表并非都是字符串格式的URL。Scrapy希望得到的是Request对象,它可以携带比字符串格式的URL更多的东西,比如cookies或者回调。功能等。可以看到我们在创建博客正文的请求时替换了回调函数,因为默认的回调函数parse是专门用来解析文章列表等页面的,parse_post定义如下:
  
def parse_post(self, response):
item = BlogCrawlItem()
item.url = unicode(response.url)
item.raw = response.body_as_unicode()
return [item]
  这很简单。返回一个 BlogCrawlItem 并将捕获的数据放入其中。你可以在这里做一些分析。比如你可以通过XPath来解析文本和标题,但是我倾向于后期做这些事情,比如Item Pipeline或者Later Offline stage。BlogCrawlItem 是 Scrapy 自动为我们定义的一个空类,继承自 ScrapedItem。在 items.py 中,我在这里添加了一些东西:
  
from scrapy.item import ScrapedItem

class BlogCrawlItem(ScrapedItem):
def __init__(self):
ScrapedItem.__init__(self)
self.url = ''

def __str__(self):
return 'BlogCrawlItem(url: %s)' % self.url
  定义了__str__函数,只给出了URL,因为默认的__str__函数会显示所有的数据,所以看到爬取的时候,控制台日志会输出一些东西,就是把爬取到的网页的内容输出出来。-.-bb
  这样,数据就被取出来了,最后只剩下存储数据的功能了。我们通过添加流水线来实现它。由于Python在标准库中自带Sqlite3支持,所以我使用Sqlite数据库来存储数据。将 pipelines.py 的内容替换为以下代码:
  
import sqlite3
from os import path

from scrapy.core import signals
from scrapy.xlib.pydispatch import dispatcher

class SQLiteStorePipeline(object):
filename = 'data.sqlite'

def __init__(self):
self.conn = None
dispatcher.connect(self.initialize, signals.engine_started)
dispatcher.connect(self.finalize, signals.engine_stopped)

def process_item(self, domain, item):
self.conn.execute('insert into blog values(?,?,?)',
(item.url, item.raw, unicode(domain)))
return item

def initialize(self):
if path.exists(self.filename):
self.conn = sqlite3.connect(self.filename)
else:
self.conn = self.create_table(self.filename)

def finalize(self):
if self.conn is not None:
self.conn.commit()
self.conn.close()
self.conn = None

def create_table(self, filename):
conn = sqlite3.connect(filename)
conn.execute("""create table blog
(url text primary key, raw text, domain text)""")
conn.commit()
return conn
  在__init__函数中,使用dispatcher将两个信号连接到指定的函数,用于初始化和关闭数据库连接(记得关闭前commit,好像不会自动commit,如果直接关闭的话,似乎所有数据都是 Dd-.-) 丢失。当数据通过管道时,将调用 process_item 函数。这里我们将原创数据直接存入数据库,不做任何处理。如有必要,您可以添加额外的管道来提取和过滤数据,但我不会在这里详细介绍。
  最后,在 settings.py 中列出我们的管道:
  ITEM_PIPELINES = ['blog_crawl.pipelines.SQLiteStorePipeline']
  再次运行爬虫就OK了!
  PS1:Scrapy 组件
  1.Scrapy 引擎(Scrapy 引擎)
  Scrapy 引擎用于控制整个系统的数据处理流程并触发事务处理。更多详细信息,请参见以下数据处理流程。
  2.调度器(调度器)
  调度器接受来自 Scrapy 引擎的请求并将它们排序到队列中,并在 Scrapy 引擎发送请求后将它们返回给它们。
  3.下载器(下载器)
  下载器的主要职责是抓取网页并将网页内容返回给蜘蛛。
  4.蜘蛛(蜘蛛)
  Spiders 是 Scrapy 用户定义的类,用于解析网页并抓取指定 URL 返回的内容。每个蜘蛛可以处理一个域名或一组域名。换句话说,它用于定义特定的网站 爬取和解析规则。
  5.项目管道(项目管道)
  项目管道的主要职责是处理蜘蛛从网页中提取的项目。它的主要任务是澄清、验证和存储数据。当页面被蜘蛛解析后,会被发送到项目管道,数据会按照几个特定的​​顺序进行处理。每个项目管道的组件都是具有简单方法的 Python 类。他们获得项目并执行他们的方法,他们还需要确定是否需要继续进行项目管道的下一步,或者干脆将其丢弃而不进行处理。
  项目管道通常执行的过程是:
  清理HTML数据,验证解析数据(检查item是否收录必要的字段) 检查数据是否重复(如果重复则删除) 将解析数据存入数据库
  6.中间件(Middleware)
  中间件是 Scrapy 引擎和其他组件之间的一个钩子框架,主要是提供自定义代码来扩展 Scrapy 的功能。
  PS2:Scrapy的数据处理流程
  Scrapy整个数据处理流程由Scrapy引擎控制,其主要运行方式为:
  当引擎打开一个域名时,蜘蛛会对该域名进行处理,并要求蜘蛛获取爬取的第一个 URL。
  引擎从蜘蛛那里获取第一个需要爬取的URL,然后在调度中作为请求进行调度。
  引擎从调度程序获取接下来要抓取的页面。
  调度器将下一个爬取到的URL返回给引擎,引擎通过下载中间件发送给下载器。
  当下载器下载网页时,响应内容通过下载中间件发送给引擎。
  引擎接收下载器的响应,通过蜘蛛中间件发送给蜘蛛进行处理。
  蜘蛛处理响应并返回爬取的项目,然后向引擎发送新请求。
  引擎将抓取项目管道并向调度员发送请求。
  系统重复第二部分之后的操作,直到调度中没有请求,然后断开引擎和域之间的连接。
  相关文章 查看全部

  java爬虫抓取动态网页(深入剖析Python爬虫框架的结构与运作流程的相关内容)
  想了解深入解析Python爬虫框架Scrapy的结构和运行过程吗?在本文中,pluskid将为大家仔细讲解Scrapy框架的结构和运行过程以及一些代码示例。欢迎阅读指正,先重点说一下:Python、Scrapy、爬虫,一起学习。
  网络爬虫(Spider)是一种在互联网上爬行的机器人。当然,它通常不是实体机器人,因为网络本身也是一个虚拟的东西,所以这个“机器人”其实就是一个程序,不是爬行,而是有一定的用途,爬行的时候会采集. 一些信息。例如,谷歌有很多爬虫采集网页内容和它们之间的链接信息;另一个例子是别有用心的爬虫在互联网上采集诸如foo [at] bar [dot] com之类的东西。此外,还有一些定制的爬虫,专门针对某个网站。比如JavaEye的Robbin前段时间写了几篇专门对付恶意爬虫的博客。是的)和 网站 诸如小众软件或 LinuxToy 之类的软件通常会被整个站点抓取下来并以不同的名称挂出。其实,爬虫的基本原理非常简单。只要能上网,能分析网页,现在大多数语言都有方便的Http客户端库可以抓取网页,最简单的HTML分析可以直接使用正则规则。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。然而,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。
  爬虫的两部分是下载网页。需要考虑的问题有很多,比如如何最大限度地利用本地带宽,如何调度不同站点的web请求,以减少其他服务器的负担。在高性能的Web Crawler系统中,DNS查询也将成为亟待优化的瓶颈。此外,还有一些“配置文件”需要遵循(例如,robots.txt)。获取网页后的分析过程也很复杂。网上奇奇怪怪的东西很多,各种HTML页面出现各种错误。分析所有这些几乎是不可能的。另外,随着AJAX的普及,如何获取Javascript动态生成的内容成为了一个大问题;此外,互联网上有各种有意或无意出现的蜘蛛陷阱。如果一味的跟着超链接走,就会被困在陷阱里。比如,这个网站据说是谷歌之前宣布互联网上Unique URL的数量已经达到1万亿,所以这个人很自豪的宣布第二万亿。:D
  然而,实际上并没有多少人需要像谷歌这样的通用爬虫。通常我们构建一个爬虫来爬取一个特定的或者某个类型的网站,所谓知己知彼,百战不死,我们可以提前爬取对网站做一些分析网站 结构,事情变得容易多了。通过分析和选择有价值的链接进行跟踪,我们可以避免很多不必要的链接或蜘蛛陷阱。如果网站的结构允许选择合适的路径,我们就可以按照感兴趣的事物的一定顺序再次爬取它,这样就连URL重复的判断都可以省略了。
  比如我们要爬下pongba博客中的博客文字,通过观察,很容易发现我们对其中两个页面感兴趣:
  文章列表页面,比如首页,或者URL为/page/\d+/的页面,通过Firebug可以看到每个文章链接都在h1下的一个标签中(应该是注意Firebug的HTML面板看到的HTML代码可能和View Source看到的有些不同,如果网页中有动态修改DOM树的Javascript,前者是修改后的版本,Firebug正则化后,比如属性有引号等等,后者通常是你的蜘蛛爬取的原创内容,如果你用正则表达式分析页面或者使用的HTML Parser和Firefox有些不同,(需要特别注意). 另外,在一个类为 wp-pagenavi 的 div 中有指向不同列表页面的链接。
  文章 内容页,每个博客都有这样一个页面,比如/2008/09/11/machine-learning-and-ai-resources/,收录了文章的完整内容,这是我们的感受感兴趣的内容。
  因此,我们从首页开始,利用 wp-pagenavi 中的链接来获取其他 文章 列表页面。特别是我们定义了一个路径:只跟随Next Page的链接,这样我们就可以从头到尾依次进行一遍,省去了反复爬行判断的麻烦。另外,文章列表页上链接到具体文章的链接对应的页面就是我们真正要保存的数据页。
  这样,它实用的脚本语言写一个ad hoc爬虫来完成这个任务并不难,不过今天的主角是Scrapy,它是一个用Python编写的爬虫框架,简单轻量,非常方便,官网说已经在实际生产中使用过,所以不是玩具级别的东西。但是,目前还没有 Release 版本。您可以直接使用其 Mercurial 存储库中的源代码来安装它。不过这个东西也可以不安装直接使用,方便随时更新。文档很详细,不再赘述。
  Scrapy 使用异步网络库 Twisted 来处理网络通信。架构清晰,收录各种中间件接口,可以灵活满足各种需求。整体架构如下图所示:
  
  绿线是数据流向。从最初的URL开始,Scheduler将其交给Downloader进行下载,下载完成后交给Spider进行分析。Spider分析的结果有两种:一种是需要进一步爬取的链接。比如之前分析的“下一页”的链接,这些东西会被发回给Scheduler;另一个是需要保存的数据,发送到Item Pipeline,就是数据的后处理(详细分析、过滤、存储等)。此外,可以在数据流通道中安装各种中间件来进行必要的处理。
  具体内容将在上一个附件中介绍。
  它看起来很复杂,但使用起来非常简单。就像Rails一样,首先新建一个项目:
  
scrapy-admin.py startproject blog_crawl
  会创建一个blog_crawl目录,里面有一个scrapy-ctl.py是整个项目的控制脚本,代码全部放在子目录blog_crawl下。为了能够爬取,我们在spiders目录下新建一个mindhacks_spider.py,定义我们的Spider如下:
  
from scrapy.spider import BaseSpider

class MindhacksSpider(BaseSpider):
domain_name = "mindhacks.cn"
start_urls = ["http://mindhacks.cn/"]

def parse(self, response):
return []

SPIDER = MindhacksSpider()
  我们的MindhacksSpider继承自BaseSpider(通常直接来自scrapy.contrib.spiders.CrawlSpider,它更通用,更方便,但是为了展示数据是如何解析的,这里使用了BaseSpider),变量domain_name和start_urls是容易理解是什么意思,parse方法就是我们需要定义的回调函数。默认请求在得到响应后会调用这个回调函数。这里我们需要解析页面,返回两个结果(需要进一步爬取链接,需要保存Data)。让我觉得有点奇怪的是,它的接口定义中的两个结果居然混在一个列表中返回。我不知道为什么它是这样设计的。最后不是要把他们分开吗?总之,这里我们先写一个空函数,它只返回一个空列表。另外,定义一个“全局”变量 SPIDER,它会在 Scrapy 导入这个模块时被实例化,并且会被 Scrapy 引擎自动找到。所以你可以先运行爬虫试试:
  
./scrapy-ctl.py crawl mindhacks.cn
  会有一堆输出,可以看到爬取了,因为这是初始的URL,但是因为我们在parse函数中没有返回需要进一步爬取的URL,所以整个爬取过程只爬取了首页和结束了。下一步是分析页面。Scrapy 提供了一个非常方便的Shell(需要IPython),可以让我们做实验。使用以下命令启动 Shell:
  
./scrapy-ctl.py shell http://mindhacks.cn
  它会启动爬虫,抓取命令行指定的页面,然后进入shell。根据提示,我们有很多现成的变量可以使用。其中之一是 hxs,它是一个 HtmlXPathSelector。mindhacks 的 HTML 页面是比较标准的。直接用XPath分析非常方便。通过Firebug可以看到每个博客文章的链接都在h1下,所以在Shell中使用这个XPath表达式测试:
  
In [1]: hxs.x('//h1/a/@href').extract()
Out[1]:
[u'http://mindhacks.cn/2009/07/06/why-you-should-do-it-yourself/',
u'http://mindhacks.cn/2009/05/17/seven-years-in-nju/',
u'http://mindhacks.cn/2009/03/28/effective-learning-and-memorization/',
u'http://mindhacks.cn/2009/03/15/preconception-explained/',
u'http://mindhacks.cn/2009/03/09/first-principles-of-programming/',
u'http://mindhacks.cn/2009/02/15/why-you-should-start-blogging-now/',
u'http://mindhacks.cn/2009/02/09/writing-is-better-thinking/',
u'http://mindhacks.cn/2009/02/07/better-explained-conflicts-in-intimate-relationship/',
u'http://mindhacks.cn/2009/02/07/independence-day/',
u'http://mindhacks.cn/2009/01/18/escape-from-your-shawshank-part1/']
  这正是我们需要的 URL。另外可以找到“下一页”的链接,和其他几个页面的链接放在一个div里,但是“下一页”的链接没有title属性,所以写XPath
  
//div[@class="wp-pagenavi"]/a[not(@title)]
  但是,如果你往回翻一页,你会发现“上一页”其实是一样的,所以你需要确定链接上的文字是下一页的箭头u'\xbb',这可能有是用 XPath 编写的。去,不过好像这本身就是一个unicode转义字符,由于编码原因不清楚,直接在外面判断,最终解析函数如下:
  
def parse(self, response):
items = []
hxs = HtmlXPathSelector(response)
posts = hxs.x('//h1/a/@href').extract()
items.extend([self.make_requests_from_url(url).replace(callback=self.parse_post)
for url in posts])

page_links = hxs.x('//div[@class="wp-pagenavi"]/a[not(@title)]')
for link in page_links:
if link.x('text()').extract()[0] == u'\xbb':
url = link.x('@href').extract()[0]
items.append(self.make_requests_from_url(url))

return items
  前半部分是解析需要爬取的博客正文的链接,后半部分是给出“下一页”的链接。需要注意的是,这里返回的列表并非都是字符串格式的URL。Scrapy希望得到的是Request对象,它可以携带比字符串格式的URL更多的东西,比如cookies或者回调。功能等。可以看到我们在创建博客正文的请求时替换了回调函数,因为默认的回调函数parse是专门用来解析文章列表等页面的,parse_post定义如下:
  
def parse_post(self, response):
item = BlogCrawlItem()
item.url = unicode(response.url)
item.raw = response.body_as_unicode()
return [item]
  这很简单。返回一个 BlogCrawlItem 并将捕获的数据放入其中。你可以在这里做一些分析。比如你可以通过XPath来解析文本和标题,但是我倾向于后期做这些事情,比如Item Pipeline或者Later Offline stage。BlogCrawlItem 是 Scrapy 自动为我们定义的一个空类,继承自 ScrapedItem。在 items.py 中,我在这里添加了一些东西:
  
from scrapy.item import ScrapedItem

class BlogCrawlItem(ScrapedItem):
def __init__(self):
ScrapedItem.__init__(self)
self.url = ''

def __str__(self):
return 'BlogCrawlItem(url: %s)' % self.url
  定义了__str__函数,只给出了URL,因为默认的__str__函数会显示所有的数据,所以看到爬取的时候,控制台日志会输出一些东西,就是把爬取到的网页的内容输出出来。-.-bb
  这样,数据就被取出来了,最后只剩下存储数据的功能了。我们通过添加流水线来实现它。由于Python在标准库中自带Sqlite3支持,所以我使用Sqlite数据库来存储数据。将 pipelines.py 的内容替换为以下代码:
  
import sqlite3
from os import path

from scrapy.core import signals
from scrapy.xlib.pydispatch import dispatcher

class SQLiteStorePipeline(object):
filename = 'data.sqlite'

def __init__(self):
self.conn = None
dispatcher.connect(self.initialize, signals.engine_started)
dispatcher.connect(self.finalize, signals.engine_stopped)

def process_item(self, domain, item):
self.conn.execute('insert into blog values(?,?,?)',
(item.url, item.raw, unicode(domain)))
return item

def initialize(self):
if path.exists(self.filename):
self.conn = sqlite3.connect(self.filename)
else:
self.conn = self.create_table(self.filename)

def finalize(self):
if self.conn is not None:
self.conn.commit()
self.conn.close()
self.conn = None

def create_table(self, filename):
conn = sqlite3.connect(filename)
conn.execute("""create table blog
(url text primary key, raw text, domain text)""")
conn.commit()
return conn
  在__init__函数中,使用dispatcher将两个信号连接到指定的函数,用于初始化和关闭数据库连接(记得关闭前commit,好像不会自动commit,如果直接关闭的话,似乎所有数据都是 Dd-.-) 丢失。当数据通过管道时,将调用 process_item 函数。这里我们将原创数据直接存入数据库,不做任何处理。如有必要,您可以添加额外的管道来提取和过滤数据,但我不会在这里详细介绍。
  最后,在 settings.py 中列出我们的管道:
  ITEM_PIPELINES = ['blog_crawl.pipelines.SQLiteStorePipeline']
  再次运行爬虫就OK了!
  PS1:Scrapy 组件
  1.Scrapy 引擎(Scrapy 引擎)
  Scrapy 引擎用于控制整个系统的数据处理流程并触发事务处理。更多详细信息,请参见以下数据处理流程。
  2.调度器(调度器)
  调度器接受来自 Scrapy 引擎的请求并将它们排序到队列中,并在 Scrapy 引擎发送请求后将它们返回给它们。
  3.下载器(下载器)
  下载器的主要职责是抓取网页并将网页内容返回给蜘蛛。
  4.蜘蛛(蜘蛛)
  Spiders 是 Scrapy 用户定义的类,用于解析网页并抓取指定 URL 返回的内容。每个蜘蛛可以处理一个域名或一组域名。换句话说,它用于定义特定的网站 爬取和解析规则。
  5.项目管道(项目管道)
  项目管道的主要职责是处理蜘蛛从网页中提取的项目。它的主要任务是澄清、验证和存储数据。当页面被蜘蛛解析后,会被发送到项目管道,数据会按照几个特定的​​顺序进行处理。每个项目管道的组件都是具有简单方法的 Python 类。他们获得项目并执行他们的方法,他们还需要确定是否需要继续进行项目管道的下一步,或者干脆将其丢弃而不进行处理。
  项目管道通常执行的过程是:
  清理HTML数据,验证解析数据(检查item是否收录必要的字段) 检查数据是否重复(如果重复则删除) 将解析数据存入数据库
  6.中间件(Middleware)
  中间件是 Scrapy 引擎和其他组件之间的一个钩子框架,主要是提供自定义代码来扩展 Scrapy 的功能。
  PS2:Scrapy的数据处理流程
  Scrapy整个数据处理流程由Scrapy引擎控制,其主要运行方式为:
  当引擎打开一个域名时,蜘蛛会对该域名进行处理,并要求蜘蛛获取爬取的第一个 URL。
  引擎从蜘蛛那里获取第一个需要爬取的URL,然后在调度中作为请求进行调度。
  引擎从调度程序获取接下来要抓取的页面。
  调度器将下一个爬取到的URL返回给引擎,引擎通过下载中间件发送给下载器。
  当下载器下载网页时,响应内容通过下载中间件发送给引擎。
  引擎接收下载器的响应,通过蜘蛛中间件发送给蜘蛛进行处理。
  蜘蛛处理响应并返回爬取的项目,然后向引擎发送新请求。
  引擎将抓取项目管道并向调度员发送请求。
  系统重复第二部分之后的操作,直到调度中没有请求,然后断开引擎和域之间的连接。
  相关文章

java爬虫抓取动态网页(爬虫多IP抓取怎么获取大量IP?方法有哪些?)

网站优化优采云 发表了文章 • 0 个评论 • 46 次浏览 • 2021-12-06 16:19 • 来自相关话题

  java爬虫抓取动态网页(爬虫多IP抓取怎么获取大量IP?方法有哪些?)
  网络爬虫如何获取大量动态IP进行数据抓取?通常在爬取数据的时候,数据量比较大,单个爬虫的爬取速度太慢。使用爬虫时,需要多个爬虫进行爬取。这时候就需要使用IP代理,使用多个动态IP进行爬取。抓取可以提高爬虫效率,同时降低单个IP访问频率,降低风险。
  
  那么爬虫是如何抓取大量IP的呢?比如对于数据采集,我们使用分布式网络爬虫,使用多台服务器,多个IP,多个slave网络爬虫同时运行,master负责调度。效率更高,属于大规模分布式爬取。一般使用Redis分布式爬取。
  那么这个IP是怎么来的呢?IP地址仍然缺乏,我们仍然使用动态IP地址,那么如何更改IP地址?爬虫使用的IP地址可不是那么简单的几个。它们需要轮流使用。抓取的网页越多,需要的 IP 就越多。否则同一个IP访问次数过多。即使访问频率不快,仍然会引起网站的关注,限制访问。
  获取IP地址的方法有:
  根据ADSL拨号服务器修改IP。每次拨号都会有一个新的IP,更好的解决了IP单一的问题。
  如果是带路由器的局域网,第一种方法可能效果不好。这时候可以模拟登录路由器,控制路由器重拨,修改IP。这其实是一种折衷的方法,曲线救国。
  代理IP,使用网上购买或爬取的免费代理IP,实现多IP网络爬取。
  不过免费代理IP的效果不是很好。你可以自己做,所以我不会在这里谈论它。为了爬取的效率,小编还是推荐购买代理IP,比如IP精灵的动态拨号vps。综上所述,爬虫可以抓取多个IP,获取IP的方式有多种。至于选择哪种方式,要看你需要的IP数量和IP的质量。 查看全部

  java爬虫抓取动态网页(爬虫多IP抓取怎么获取大量IP?方法有哪些?)
  网络爬虫如何获取大量动态IP进行数据抓取?通常在爬取数据的时候,数据量比较大,单个爬虫的爬取速度太慢。使用爬虫时,需要多个爬虫进行爬取。这时候就需要使用IP代理,使用多个动态IP进行爬取。抓取可以提高爬虫效率,同时降低单个IP访问频率,降低风险。
  
  那么爬虫是如何抓取大量IP的呢?比如对于数据采集,我们使用分布式网络爬虫,使用多台服务器,多个IP,多个slave网络爬虫同时运行,master负责调度。效率更高,属于大规模分布式爬取。一般使用Redis分布式爬取。
  那么这个IP是怎么来的呢?IP地址仍然缺乏,我们仍然使用动态IP地址,那么如何更改IP地址?爬虫使用的IP地址可不是那么简单的几个。它们需要轮流使用。抓取的网页越多,需要的 IP 就越多。否则同一个IP访问次数过多。即使访问频率不快,仍然会引起网站的关注,限制访问。
  获取IP地址的方法有:
  根据ADSL拨号服务器修改IP。每次拨号都会有一个新的IP,更好的解决了IP单一的问题。
  如果是带路由器的局域网,第一种方法可能效果不好。这时候可以模拟登录路由器,控制路由器重拨,修改IP。这其实是一种折衷的方法,曲线救国。
  代理IP,使用网上购买或爬取的免费代理IP,实现多IP网络爬取。
  不过免费代理IP的效果不是很好。你可以自己做,所以我不会在这里谈论它。为了爬取的效率,小编还是推荐购买代理IP,比如IP精灵的动态拨号vps。综上所述,爬虫可以抓取多个IP,获取IP的方式有多种。至于选择哪种方式,要看你需要的IP数量和IP的质量。

java爬虫抓取动态网页(爬虫科普一下对爬虫的误区、原理以及实现(组图))

网站优化优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2021-12-06 11:03 • 来自相关话题

  java爬虫抓取动态网页(爬虫科普一下对爬虫的误区、原理以及实现(组图))
  爬虫?相信很多人都熟悉这个词。简单的说就是利用工具对网页上的数据进行爬取,并进行排序和分析。照例告诉小白爬虫的误区、原理和实现。
  爬虫常见误区:python=爬虫?
  很多新手都会把python等同于爬虫。其实python是一种计算机编程语言。它不仅可以做爬虫,还可以构建Web应用程序。最近很火的人工智能也可以用python语言来实现。的。
  爬虫的本质是抓取服务器响应浏览器的数据(原理会在下面详述)。Java、C#等不同的计算机编程语言都可以实现爬虫。
  总结:python≠爬虫,python的功能远比我们想象的要强大,爬虫不仅仅只有python才有可能。
  履带原理
  让我们回忆一下我们访问百度时的过程:
  1.在地址栏中输入网址:
  肯定有人会说我以前从来没有这样做过。我一直都是用浏览器打开导航进入百度。
  其实这种方式进入百度,只不过是浏览器为你输入了访问百度的链接。
  2. 浏览器刷新了,百度的搜索框出现在我们面前。
  当然网速不能刷新的情况就不考虑了。
  在此期间,浏览器和服务器之间发生了什么?
  1. 浏览器向服务器发送URL,即请求的地址。
  2. 服务器收到浏览器的网络请求,开始向浏览器响应数据。
  3. 浏览器接收服务器发送来的数据,进行分析,显示出来。
  有兴趣的可以清除浏览器缓存,使用Fn+F12组合键打开浏览器控制台,选择NetWork菜单,可以看到页面刷新时的具体响应过程
  爬虫的实现机制
  1.既然浏览器可以将请求地址发送到服务器,我们也可以通过程序向服务器发起请求。
  2.既然浏览器可以接收到服务器发来的数据,我们就可以模仿浏览器的解析过程,过滤得到我们想要的数据。
  总结:通过我们自己的程序,不需要反复组织我们想要的数据。所有这些都是由我们的爬虫程序完成的。
  Java爬虫的具体案例
  目标:抓取动态模块显示的最新新闻,并将新闻内容以文件形式保存在本地。
  
  爬取资源 1
  
  爬取资源2
  (一) 需求分析
  1.新闻网首页解析,抓取部门动态模块内容
  2.模拟跳转,进入各个新闻页面,抓取新闻的具体内容
  3.将新闻的具体内容保存在一个文件中
  (二)代码实现
  1.使用maven工具,在pom.xml中导入我们爬虫依赖的jar包
  


org.apache.httpcomponents
httpclient
4.5.3



org.jsoup
jsoup
1.8.3



log4j
log4j
1.2.16



junit
junit
4.10


  2. 做一个发送请求的简单类
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
public class MyClient {
public String getContent(String url) throws ClientProtocolException, IOException {
// 创建httpclient对象
HttpClient hClient = new DefaultHttpClient();
// 设置连接超时时间,响应超时时间,以及代理服务器
hClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000)
.setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
.setParameter(ConnRouteParams.DEFAULT_PROXY, new HttpHost("117.191.11.71", 8080));
// 创建get请求对象
HttpGet hGet = new HttpGet(url);
// 模拟请求,获得服务器响应的源码
HttpResponse response = hClient.execute(hGet);
// 将源码转换为字符串
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
// 返回转化后的字符串
return content;
}
}
  3. 做一个解析服务器数据的类
  package com.sxau.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class MyJsoup {
public Elements getTarget(
String htmlResource,String selectCondition) {
//解析服务器发来的数据
Document doc = Jsoup.parse(htmlResource);
//对解析后的数据通过条件筛选
Elements elements = doc.select(selectCondition);
return elements;
}
}
  4. 制作一个类在本地存储文件
  package com.sxau.example;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class MyFileIO {
public void makeFile(String title,String txtContent) throws IOException {
//将标题左右多余的空格去掉
title = title.trim();
//拿到当前应用所在路径
String property = System.getProperty("user.dir");
//设置生成文件的路径与名称
String filePath = property + "\\src\\main\\webapp\\spidertxt\\" + title + ".txt";
//生成新文件
File txt = new File(filePath);
//将文件输入器定位到刚刚生成的新文件
FileWriter writer = new FileWriter(txt);
//将已经匹配的字符串写入文件中
writer.write(txtContent);
//刷新并关闭流
writer.flush();
writer.close();
}
}
  5. 为了提高效率,创建线程并发处理
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.select.Elements;
/**
* 实现Runable接口
* @author Administrator
*
*/
public class MyThread implements Runnable{

private String mainUrl;
private String singleUrl;
//提供有参数的构造方法,确保进入页面时url不为空
public MyThread(String mainUrl, String singleUrl) {
this.mainUrl = mainUrl;
this.singleUrl = singleUrl;
}
/**
* 实现接口未实现的run()方法
* 通过httpclient发送请求并接收数据
* 观察html页面,使用jsoup中便捷的仿css/js选择器语法得到我们需要的内容
* 对匹配好的字符串进行优化,并进行本地存储
*/
@Override
public void run() {
// TODO 自动生成的方法存根
MyClient myClient = new MyClient();
String url=mainUrl+singleUrl;
String content;
try {
content = myClient.getContent(url);
String selectCondition1=".arti_title";
String selectCondition2=".wp_articlecontent";
MyJsoup jsoup = new MyJsoup();
Elements elements1 = jsoup.getTarget(content, selectCondition1);
Elements elements2 = jsoup.getTarget(content, selectCondition2);
String html1 = elements1.get(0).html();
String title = html1.replaceAll("", "");
String html2 = elements2.get(0).html();
html2 = html2.replaceAll("<p>", "");
String word = html2.replaceAll("", "");
MyFileIO fileIO=new MyFileIO();
fileIO.makeFile(title, word);
} catch (ClientProtocolException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

}

}
</p>
  6.制作主程序
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class MySpider {
public static void main(String[] args) throws ClientProtocolException, IOException {
MyClient myClient = new MyClient();
String url="http://news.sxau.edu.cn/";
String content = myClient.getContent(url);
String selectCondition="a[href][title~=(|)]";
MyJsoup jsoup = new MyJsoup();
Elements elements = jsoup.getTarget(content, selectCondition);
for (Element element : elements) {
String attr = element.attr("href");
new Thread(new MyThread(url, attr)).start();
}
System.out.println("文件爬虫成功!");
}
}
  6.运行mian方法,稍等片刻,刚出炉的文件已经静静的躺在文件夹里了。
  log4j:WARN No appenders could be found for logger (org.apache.http.impl.conn.BasicClientConnectionManager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4 ... onfig for more info.
文件爬虫成功!
  
  最终效果
  至此,一个简单的爬虫功能已经实现。菜鸟们,有什么问题,欢迎大家赐教,互相探讨,共同进步。 查看全部

  java爬虫抓取动态网页(爬虫科普一下对爬虫的误区、原理以及实现(组图))
  爬虫?相信很多人都熟悉这个词。简单的说就是利用工具对网页上的数据进行爬取,并进行排序和分析。照例告诉小白爬虫的误区、原理和实现。
  爬虫常见误区:python=爬虫?
  很多新手都会把python等同于爬虫。其实python是一种计算机编程语言。它不仅可以做爬虫,还可以构建Web应用程序。最近很火的人工智能也可以用python语言来实现。的。
  爬虫的本质是抓取服务器响应浏览器的数据(原理会在下面详述)。Java、C#等不同的计算机编程语言都可以实现爬虫。
  总结:python≠爬虫,python的功能远比我们想象的要强大,爬虫不仅仅只有python才有可能。
  履带原理
  让我们回忆一下我们访问百度时的过程:
  1.在地址栏中输入网址:
  肯定有人会说我以前从来没有这样做过。我一直都是用浏览器打开导航进入百度。
  其实这种方式进入百度,只不过是浏览器为你输入了访问百度的链接。
  2. 浏览器刷新了,百度的搜索框出现在我们面前。
  当然网速不能刷新的情况就不考虑了。
  在此期间,浏览器和服务器之间发生了什么?
  1. 浏览器向服务器发送URL,即请求的地址。
  2. 服务器收到浏览器的网络请求,开始向浏览器响应数据。
  3. 浏览器接收服务器发送来的数据,进行分析,显示出来。
  有兴趣的可以清除浏览器缓存,使用Fn+F12组合键打开浏览器控制台,选择NetWork菜单,可以看到页面刷新时的具体响应过程
  爬虫的实现机制
  1.既然浏览器可以将请求地址发送到服务器,我们也可以通过程序向服务器发起请求。
  2.既然浏览器可以接收到服务器发来的数据,我们就可以模仿浏览器的解析过程,过滤得到我们想要的数据。
  总结:通过我们自己的程序,不需要反复组织我们想要的数据。所有这些都是由我们的爬虫程序完成的。
  Java爬虫的具体案例
  目标:抓取动态模块显示的最新新闻,并将新闻内容以文件形式保存在本地。
  
  爬取资源 1
  
  爬取资源2
  (一) 需求分析
  1.新闻网首页解析,抓取部门动态模块内容
  2.模拟跳转,进入各个新闻页面,抓取新闻的具体内容
  3.将新闻的具体内容保存在一个文件中
  (二)代码实现
  1.使用maven工具,在pom.xml中导入我们爬虫依赖的jar包
  


org.apache.httpcomponents
httpclient
4.5.3



org.jsoup
jsoup
1.8.3



log4j
log4j
1.2.16



junit
junit
4.10


  2. 做一个发送请求的简单类
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
public class MyClient {
public String getContent(String url) throws ClientProtocolException, IOException {
// 创建httpclient对象
HttpClient hClient = new DefaultHttpClient();
// 设置连接超时时间,响应超时时间,以及代理服务器
hClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000)
.setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
.setParameter(ConnRouteParams.DEFAULT_PROXY, new HttpHost("117.191.11.71", 8080));
// 创建get请求对象
HttpGet hGet = new HttpGet(url);
// 模拟请求,获得服务器响应的源码
HttpResponse response = hClient.execute(hGet);
// 将源码转换为字符串
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
// 返回转化后的字符串
return content;
}
}
  3. 做一个解析服务器数据的类
  package com.sxau.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class MyJsoup {
public Elements getTarget(
String htmlResource,String selectCondition) {
//解析服务器发来的数据
Document doc = Jsoup.parse(htmlResource);
//对解析后的数据通过条件筛选
Elements elements = doc.select(selectCondition);
return elements;
}
}
  4. 制作一个类在本地存储文件
  package com.sxau.example;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class MyFileIO {
public void makeFile(String title,String txtContent) throws IOException {
//将标题左右多余的空格去掉
title = title.trim();
//拿到当前应用所在路径
String property = System.getProperty("user.dir");
//设置生成文件的路径与名称
String filePath = property + "\\src\\main\\webapp\\spidertxt\\" + title + ".txt";
//生成新文件
File txt = new File(filePath);
//将文件输入器定位到刚刚生成的新文件
FileWriter writer = new FileWriter(txt);
//将已经匹配的字符串写入文件中
writer.write(txtContent);
//刷新并关闭流
writer.flush();
writer.close();
}
}
  5. 为了提高效率,创建线程并发处理
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.select.Elements;
/**
* 实现Runable接口
* @author Administrator
*
*/
public class MyThread implements Runnable{

private String mainUrl;
private String singleUrl;
//提供有参数的构造方法,确保进入页面时url不为空
public MyThread(String mainUrl, String singleUrl) {
this.mainUrl = mainUrl;
this.singleUrl = singleUrl;
}
/**
* 实现接口未实现的run()方法
* 通过httpclient发送请求并接收数据
* 观察html页面,使用jsoup中便捷的仿css/js选择器语法得到我们需要的内容
* 对匹配好的字符串进行优化,并进行本地存储
*/
@Override
public void run() {
// TODO 自动生成的方法存根
MyClient myClient = new MyClient();
String url=mainUrl+singleUrl;
String content;
try {
content = myClient.getContent(url);
String selectCondition1=".arti_title";
String selectCondition2=".wp_articlecontent";
MyJsoup jsoup = new MyJsoup();
Elements elements1 = jsoup.getTarget(content, selectCondition1);
Elements elements2 = jsoup.getTarget(content, selectCondition2);
String html1 = elements1.get(0).html();
String title = html1.replaceAll("", "");
String html2 = elements2.get(0).html();
html2 = html2.replaceAll("<p>", "");
String word = html2.replaceAll("", "");
MyFileIO fileIO=new MyFileIO();
fileIO.makeFile(title, word);
} catch (ClientProtocolException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

}

}
</p>
  6.制作主程序
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class MySpider {
public static void main(String[] args) throws ClientProtocolException, IOException {
MyClient myClient = new MyClient();
String url="http://news.sxau.edu.cn/";
String content = myClient.getContent(url);
String selectCondition="a[href][title~=(|)]";
MyJsoup jsoup = new MyJsoup();
Elements elements = jsoup.getTarget(content, selectCondition);
for (Element element : elements) {
String attr = element.attr("href");
new Thread(new MyThread(url, attr)).start();
}
System.out.println("文件爬虫成功!");
}
}
  6.运行mian方法,稍等片刻,刚出炉的文件已经静静的躺在文件夹里了。
  log4j:WARN No appenders could be found for logger (org.apache.http.impl.conn.BasicClientConnectionManager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4 ... onfig for more info.
文件爬虫成功!
  
  最终效果
  至此,一个简单的爬虫功能已经实现。菜鸟们,有什么问题,欢迎大家赐教,互相探讨,共同进步。

java爬虫抓取动态网页(java爬虫抓取动态网页的内容,不是专业的不懂)

网站优化优采云 发表了文章 • 0 个评论 • 37 次浏览 • 2021-12-03 20:12 • 来自相关话题

  java爬虫抓取动态网页(java爬虫抓取动态网页的内容,不是专业的不懂)
  java爬虫抓取动态网页的内容,不是java专业的不懂,但我能给的建议是换html页面,markdown语言解析html文本,然后对其进行解析抓取。其实也可以考虑一下python,它抓取和解析html的能力都不错。
  我个人更倾向于go,为啥不选一个爬虫程序作为主力来爬虫?自己学程序解析html,js解析等等,
  先全换成c#,再半伪代码半java,最后全换成pythonjava等动态语言。要解决的问题要有先后顺序。我没见过爬虫程序从全伪代码半java改成从只有java到解析html等动态语言的,
  可以看一下我的golang学习总结系列文章golang快速入门总结:上一篇:golang快速入门总结:数据分析、机器学习、爬虫系列文章;下一篇:golang快速入门总结:动态网页爬取系列文章;
  我没有经历过爬虫的全过程,只能给出一些有针对性的方法。你的开发环境是怎么样的,可以统一安装一些爬虫环境。第一步,把你手头已有的网站爬下来,然后封装成api。但你做过网站的代码审查。怎么让你需要的网站用go开发都给你封装好。第二步,封装好api之后,可以把url里面的参数,将这些参数封装成一个或多个类方法,每个方法里面封装对应的参数(单个参数是无法通过api获取)。
  这样就实现了python爬虫的后面两步。同时,用java来写代码就很容易。你需要从头写起。如果你以前没有做过爬虫,那么需要补一下java相关的基础知识。 查看全部

  java爬虫抓取动态网页(java爬虫抓取动态网页的内容,不是专业的不懂)
  java爬虫抓取动态网页的内容,不是java专业的不懂,但我能给的建议是换html页面,markdown语言解析html文本,然后对其进行解析抓取。其实也可以考虑一下python,它抓取和解析html的能力都不错。
  我个人更倾向于go,为啥不选一个爬虫程序作为主力来爬虫?自己学程序解析html,js解析等等,
  先全换成c#,再半伪代码半java,最后全换成pythonjava等动态语言。要解决的问题要有先后顺序。我没见过爬虫程序从全伪代码半java改成从只有java到解析html等动态语言的,
  可以看一下我的golang学习总结系列文章golang快速入门总结:上一篇:golang快速入门总结:数据分析、机器学习、爬虫系列文章;下一篇:golang快速入门总结:动态网页爬取系列文章;
  我没有经历过爬虫的全过程,只能给出一些有针对性的方法。你的开发环境是怎么样的,可以统一安装一些爬虫环境。第一步,把你手头已有的网站爬下来,然后封装成api。但你做过网站的代码审查。怎么让你需要的网站用go开发都给你封装好。第二步,封装好api之后,可以把url里面的参数,将这些参数封装成一个或多个类方法,每个方法里面封装对应的参数(单个参数是无法通过api获取)。
  这样就实现了python爬虫的后面两步。同时,用java来写代码就很容易。你需要从头写起。如果你以前没有做过爬虫,那么需要补一下java相关的基础知识。

java爬虫抓取动态网页(实战|手把手教你用Python爬虫(附详细源码)(图))

网站优化优采云 发表了文章 • 0 个评论 • 49 次浏览 • 2021-12-01 18:10 • 来自相关话题

  java爬虫抓取动态网页(实战|手把手教你用Python爬虫(附详细源码)(图))
  项目背景
  事情是这样的。前几天,我的公众号写了一篇实战爬虫入口文章,名为《实战|教你使用Python爬虫(附详细源码)》。发出后不到一天,一位从业10年的王律师找上我。虽然同意了他的微信申请,但心里还是有些慌。
  点击此处获取海量Python学习资料!
  
  短暂交流后,原来他是在自学爬虫,结果翻页发现网址没变。其实他爬取的网页难度比较大,也就是这次要详细介绍的动态网页。一向乐于助人的J哥,自然会在最短的时间内给他指明方向,从青铜到白银。
  AJAX 动态加载网页
  一
  什么是动态网页
  J哥一向注重理论与实践的结合,知其然也必知其所以然,才能应付一切变化而无变化。
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。——来源百度百科
  动态网页具有工作量少、内容更新快、功能更齐全的特点。被很多公司采用,如购动、速食宝、速食等。
  二
  什么是 AJAX
  随着人们对动态网页的加载速度要求越来越高,AJAX 技术应运而生,成为许多网站的首选。AJAX 是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,使网页可以异步更新。这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。
  三
  如何抓取AJAX动态加载的网页
  1. 分析界面
  只要有数据发送,就一定有请求发送到服务器。我们只需要找出它静默加载的页面的真实请求。特点:爬取速度快,爬取数据干净,部分网站比较难解析。
  2. 硒
  什么是硒?它最初是一个自动化测试工具,但它被广泛的用户抓取。是一个可以用代码操作浏览器的工具,比如控制浏览器的下滑,模拟鼠标点击等。 特点:代码比较简单,爬取速度慢,IP容易被封。
  项目实践
  理论这么多,老实说,J哥也不想这么啰嗦。但是,这些东西经常被问到,所以把它们写下来。下次有人问,就送他这个文章,一劳永逸!
  
  好,让我们回到王律师的部分。作为资深律师,王律师深知,研究法院多年来公开的开庭信息和执行信息,对于提升业务能力具有重要作用。于是他兴高采烈地打开了法庭信息公开网页。
  它看起来像这样:
  
  然后,他按照J哥之前写的爬虫介绍文章抓取数据,成功提取到第一页。他异常兴奋。
  
  紧接着,他又加了一个for循环,想着花几分钟把这个网站2164页共32457条宣判数据提取到excel中。
  然后,就没有了。你也应该知道,看了前面的理论部分,这是一个AJAX动态加载的网页。无论你如何点击下一页,url都不会改变。如果你不相信我,我就给你看。左上角的url像山一样矗立在那里:
  
  一
  解析接口
  既然如此,那我们就开始爬虫的正确姿势,先用解析接口的方法来写爬虫。
  首先,找到真正的请求。右键勾选,点击Network,选择XHR,刷新网页,在Name列表中选择jsp文件。没错,就是这么简单,真正的要求就藏在里面。
  
  再仔细看看这个jsp,这简直就是宝藏。有真实的请求url、post请求方法、Headers、Form Data,From Data代表传递给url的参数。通过改变参数,我们可以得到数据!为了安全起见,我为我的 Cookie 做了马赛克。机智的朋友可能已经发现我顺便给自己打了广告。
  
  让我们仔细看看这些参数, pagesnum 参数不仅仅代表页数!王律师顿时恍然大悟,原来他思考的那一页,竟然翻到了这里!穿越千山万水,终于找到了你!我们尝试点击翻页,发现只有 pagesnum 参数会发生变化。
  
  既然找到了,赶紧抓起来吧。J哥以闪电般的速度打开了PyCharm,导入了爬虫需要的库。
  1from urllib.parse import urlencode
2import csv
3import random
4import requests
5import traceback
6from time import sleep
7from lxml import etree #lxml为第三方网页解析库,强大且速度快
  构造一个真正的请求并添加标题。J哥没有把他的User-Agent和Cookie贴在这里,主要是一向胆小的J哥被吓到了。
   1base_url = &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B #这里要换成对应Ajax请求中的链接
2
3headers = {
4 &#39;Connection&#39;: &#39;keep-alive&#39;,
5 &#39;Accept&#39;: &#39;*/*&#39;,
6 &#39;X-Requested-With&#39;: &#39;XMLHttpRequest&#39;,
7 &#39;User-Agent&#39;: &#39;你的User-Agent&#39;,
8 &#39;Origin&#39;: &#39;http://www.hshfy.sh.cn&#39;,
9 &#39;Referer&#39;: &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B,
10 &#39;Accept-Language&#39;: &#39;zh-CN,zh;q=0.9&#39;,
11 &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;,
12 &#39;Cookie&#39;: &#39;你的Cookie&#39;
13}
  构造get_page函数,参数为page,即页数。创建字典类型的表单数据,并使用post请求网页数据。这里一定要注意对返回数据的解码,编码为'gbk',否则返回数据会出现乱码!另外,我还优化了异常处理,防止意外。
   1def get_page(page):
2 n = 3
3 while True:
4 try:
5 sleep(random.uniform(1, 2)) # 随机出现1-2之间的数,包含小数
6 data = {
7 &#39;yzm&#39;: &#39;yxAH&#39;,
8 &#39;ft&#39;:&#39;&#39;,
9 &#39;ktrqks&#39;: &#39;2020-05-22&#39;,
10 &#39;ktrqjs&#39;: &#39;2020-06-22&#39;,
11 &#39;spc&#39;:&#39;&#39;,
12 &#39;yg&#39;:&#39;&#39;,
13 &#39;bg&#39;:&#39;&#39;,
14 &#39;ah&#39;:&#39;&#39;,
15 &#39;pagesnum&#39;: page
16 }
17 url = base_url + urlencode(data)
18 print(url)
19 try:
20 response = requests.request("POST",url, headers = headers)
21 #print(response)
22 if response.status_code == 200:
23 re = response.content.decode(&#39;gbk&#39;)
24 # print(re)
25 return re # 解析内容
26 except requests.ConnectionError as e:
27 print(&#39;Error&#39;, e.args) # 输出异常信息
28 except (TimeoutError, Exception):
29 n -= 1
30 if n == 0:
31 print(&#39;请求3次均失败,放弃此url请求,检查请求条件&#39;)
32 return
33 else:
34 print(&#39;请求失败,重新请求&#39;)
35 continue
  构造parse_page函数解析返回的网页数据,用Xpath提取所有字段内容,并保存为csv格式。有人会问为什么J哥那么喜欢用Xpath,因为它简单好用!!!这么简单的网页结构,我做不了普通的大法安装。J兄弟,我做不到。
   1def parse_page(html):
2 try:
3 parse = etree.HTML(html) # 解析网页
4 items = parse.xpath(&#39;//*[@id="report"]/tbody/tr&#39;)
5 for item in items[1:]:
6 item = {
7 &#39;a&#39;: &#39;&#39;.join(item.xpath(&#39;./td[1]/font/text()&#39;)).strip(),
8 &#39;b&#39;: &#39;&#39;.join(item.xpath(&#39;./td[2]/font/text()&#39;)).strip(),
9 &#39;c&#39;: &#39;&#39;.join(item.xpath(&#39;./td[3]/text()&#39;)).strip(),
10 &#39;d&#39;: &#39;&#39;.join(item.xpath(&#39;./td[4]/text()&#39;)).strip(),
11 &#39;e&#39;: &#39;&#39;.join(item.xpath(&#39;./td[5]/text()&#39;)).strip(),
12 &#39;f&#39;: &#39;&#39;.join(item.xpath(&#39;./td[6]/div/text()&#39;)).strip(),
13 &#39;g&#39;: &#39;&#39;.join(item.xpath(&#39;./td[7]/div/text()&#39;)).strip(),
14 &#39;h&#39;: &#39;&#39;.join(item.xpath(&#39;./td[8]/text()&#39;)).strip(),
15 &#39;i&#39;: &#39;&#39;.join(item.xpath(&#39;./td[9]/text()&#39;)).strip()
16 }
17 #print(item)
18 try:
19 with open(&#39;./law.csv&#39;, &#39;a&#39;, encoding=&#39;utf_8_sig&#39;, newline=&#39;&#39;) as fp:
20 # &#39;a&#39;为追加模式(添加)
21 # utf_8_sig格式导出csv不乱码
22 fieldnames = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;,&#39;f&#39;,&#39;g&#39;,&#39;h&#39;,&#39;i&#39;]
23 writer = csv.DictWriter(fp,fieldnames)
24 writer.writerow(item)
25 except Exception:
26 print(traceback.print_exc()) #代替print e 来输出详细的异常信息
27 except Exception:
28 print(traceback.print_exc())
  最后遍历页数,调用函数。OK完成!
  1 for page in range(1,5): #这里设置想要爬取的页数
2 html = get_page(page)
3 #print(html)
4 print("第" + str(page) + "页提取完成")
  我们来看看最终的效果:
  
  二
  硒
  渴望学习的朋友可能还想看看Selenium是如何爬取AJAX动态加载的网页的。J哥自然会满足你的好奇心。于是赶紧新建了一个py文件,准备趁势而上,用Selenium把这个网站爬下来。
  首先,导入相关库。
  1from lxml import etree
2import time
3from selenium import webdriver
4from selenium. webdriver.support.wait import WebDriverWait
5from selenium.webdriver.support import expected_conditions as EC
6from selenium.webdriver.common.by import By
  然后,使用chromedriver驱动打开这个网站。
  1def main():
2 # 爬取首页url
3 url = "http://www.hshfy.sh.cn/shfy/gw ... ot%3B
4 # 定义谷歌webdriver
5 driver = webdriver.Chrome(&#39;./chromedriver&#39;)
6 driver.maximize_window() # 将浏览器最大化
7 driver.get(url)
  所以,我惊讶地发现报告了一个错误。以CET-6英语的词汇储备,J哥居然听懂了!可能是我的驱动和浏览器版本不匹配,只支持79版本的浏览器。
  J兄很郁闷,因为我以前用Selenium从来没有遇到过这种问题。J哥不甘心,打开谷歌浏览器查看版本号。
  
  我失去了它!都更新到了81版!遇到这种情况,请好奇的朋友等待J哥设置浏览器自动更新并重新下载最新驱动,下次再来听听Selenium爬虫吧。记得关注本公众号,不要错过精彩哦~
  综上所述,对于网络爬虫的AJAX动态加载,一般有两种方式:解析接口;硒。J兄推荐解析接口的方式。如果是解析json数据,最好是爬取。如果你不知道如何使用Selenium,让我们使用Selenium。 查看全部

  java爬虫抓取动态网页(实战|手把手教你用Python爬虫(附详细源码)(图))
  项目背景
  事情是这样的。前几天,我的公众号写了一篇实战爬虫入口文章,名为《实战|教你使用Python爬虫(附详细源码)》。发出后不到一天,一位从业10年的王律师找上我。虽然同意了他的微信申请,但心里还是有些慌。
  点击此处获取海量Python学习资料!
  
  短暂交流后,原来他是在自学爬虫,结果翻页发现网址没变。其实他爬取的网页难度比较大,也就是这次要详细介绍的动态网页。一向乐于助人的J哥,自然会在最短的时间内给他指明方向,从青铜到白银。
  AJAX 动态加载网页
  一
  什么是动态网页
  J哥一向注重理论与实践的结合,知其然也必知其所以然,才能应付一切变化而无变化。
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。——来源百度百科
  动态网页具有工作量少、内容更新快、功能更齐全的特点。被很多公司采用,如购动、速食宝、速食等。
  二
  什么是 AJAX
  随着人们对动态网页的加载速度要求越来越高,AJAX 技术应运而生,成为许多网站的首选。AJAX 是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,使网页可以异步更新。这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。
  三
  如何抓取AJAX动态加载的网页
  1. 分析界面
  只要有数据发送,就一定有请求发送到服务器。我们只需要找出它静默加载的页面的真实请求。特点:爬取速度快,爬取数据干净,部分网站比较难解析。
  2. 硒
  什么是硒?它最初是一个自动化测试工具,但它被广泛的用户抓取。是一个可以用代码操作浏览器的工具,比如控制浏览器的下滑,模拟鼠标点击等。 特点:代码比较简单,爬取速度慢,IP容易被封。
  项目实践
  理论这么多,老实说,J哥也不想这么啰嗦。但是,这些东西经常被问到,所以把它们写下来。下次有人问,就送他这个文章,一劳永逸!
  
  好,让我们回到王律师的部分。作为资深律师,王律师深知,研究法院多年来公开的开庭信息和执行信息,对于提升业务能力具有重要作用。于是他兴高采烈地打开了法庭信息公开网页。
  它看起来像这样:
  
  然后,他按照J哥之前写的爬虫介绍文章抓取数据,成功提取到第一页。他异常兴奋。
  
  紧接着,他又加了一个for循环,想着花几分钟把这个网站2164页共32457条宣判数据提取到excel中。
  然后,就没有了。你也应该知道,看了前面的理论部分,这是一个AJAX动态加载的网页。无论你如何点击下一页,url都不会改变。如果你不相信我,我就给你看。左上角的url像山一样矗立在那里:
  
  一
  解析接口
  既然如此,那我们就开始爬虫的正确姿势,先用解析接口的方法来写爬虫。
  首先,找到真正的请求。右键勾选,点击Network,选择XHR,刷新网页,在Name列表中选择jsp文件。没错,就是这么简单,真正的要求就藏在里面。
  
  再仔细看看这个jsp,这简直就是宝藏。有真实的请求url、post请求方法、Headers、Form Data,From Data代表传递给url的参数。通过改变参数,我们可以得到数据!为了安全起见,我为我的 Cookie 做了马赛克。机智的朋友可能已经发现我顺便给自己打了广告。
  
  让我们仔细看看这些参数, pagesnum 参数不仅仅代表页数!王律师顿时恍然大悟,原来他思考的那一页,竟然翻到了这里!穿越千山万水,终于找到了你!我们尝试点击翻页,发现只有 pagesnum 参数会发生变化。
  
  既然找到了,赶紧抓起来吧。J哥以闪电般的速度打开了PyCharm,导入了爬虫需要的库。
  1from urllib.parse import urlencode
2import csv
3import random
4import requests
5import traceback
6from time import sleep
7from lxml import etree #lxml为第三方网页解析库,强大且速度快
  构造一个真正的请求并添加标题。J哥没有把他的User-Agent和Cookie贴在这里,主要是一向胆小的J哥被吓到了。
   1base_url = &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B #这里要换成对应Ajax请求中的链接
2
3headers = {
4 &#39;Connection&#39;: &#39;keep-alive&#39;,
5 &#39;Accept&#39;: &#39;*/*&#39;,
6 &#39;X-Requested-With&#39;: &#39;XMLHttpRequest&#39;,
7 &#39;User-Agent&#39;: &#39;你的User-Agent&#39;,
8 &#39;Origin&#39;: &#39;http://www.hshfy.sh.cn&#39;,
9 &#39;Referer&#39;: &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B,
10 &#39;Accept-Language&#39;: &#39;zh-CN,zh;q=0.9&#39;,
11 &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;,
12 &#39;Cookie&#39;: &#39;你的Cookie&#39;
13}
  构造get_page函数,参数为page,即页数。创建字典类型的表单数据,并使用post请求网页数据。这里一定要注意对返回数据的解码,编码为'gbk',否则返回数据会出现乱码!另外,我还优化了异常处理,防止意外。
   1def get_page(page):
2 n = 3
3 while True:
4 try:
5 sleep(random.uniform(1, 2)) # 随机出现1-2之间的数,包含小数
6 data = {
7 &#39;yzm&#39;: &#39;yxAH&#39;,
8 &#39;ft&#39;:&#39;&#39;,
9 &#39;ktrqks&#39;: &#39;2020-05-22&#39;,
10 &#39;ktrqjs&#39;: &#39;2020-06-22&#39;,
11 &#39;spc&#39;:&#39;&#39;,
12 &#39;yg&#39;:&#39;&#39;,
13 &#39;bg&#39;:&#39;&#39;,
14 &#39;ah&#39;:&#39;&#39;,
15 &#39;pagesnum&#39;: page
16 }
17 url = base_url + urlencode(data)
18 print(url)
19 try:
20 response = requests.request("POST",url, headers = headers)
21 #print(response)
22 if response.status_code == 200:
23 re = response.content.decode(&#39;gbk&#39;)
24 # print(re)
25 return re # 解析内容
26 except requests.ConnectionError as e:
27 print(&#39;Error&#39;, e.args) # 输出异常信息
28 except (TimeoutError, Exception):
29 n -= 1
30 if n == 0:
31 print(&#39;请求3次均失败,放弃此url请求,检查请求条件&#39;)
32 return
33 else:
34 print(&#39;请求失败,重新请求&#39;)
35 continue
  构造parse_page函数解析返回的网页数据,用Xpath提取所有字段内容,并保存为csv格式。有人会问为什么J哥那么喜欢用Xpath,因为它简单好用!!!这么简单的网页结构,我做不了普通的大法安装。J兄弟,我做不到。
   1def parse_page(html):
2 try:
3 parse = etree.HTML(html) # 解析网页
4 items = parse.xpath(&#39;//*[@id="report"]/tbody/tr&#39;)
5 for item in items[1:]:
6 item = {
7 &#39;a&#39;: &#39;&#39;.join(item.xpath(&#39;./td[1]/font/text()&#39;)).strip(),
8 &#39;b&#39;: &#39;&#39;.join(item.xpath(&#39;./td[2]/font/text()&#39;)).strip(),
9 &#39;c&#39;: &#39;&#39;.join(item.xpath(&#39;./td[3]/text()&#39;)).strip(),
10 &#39;d&#39;: &#39;&#39;.join(item.xpath(&#39;./td[4]/text()&#39;)).strip(),
11 &#39;e&#39;: &#39;&#39;.join(item.xpath(&#39;./td[5]/text()&#39;)).strip(),
12 &#39;f&#39;: &#39;&#39;.join(item.xpath(&#39;./td[6]/div/text()&#39;)).strip(),
13 &#39;g&#39;: &#39;&#39;.join(item.xpath(&#39;./td[7]/div/text()&#39;)).strip(),
14 &#39;h&#39;: &#39;&#39;.join(item.xpath(&#39;./td[8]/text()&#39;)).strip(),
15 &#39;i&#39;: &#39;&#39;.join(item.xpath(&#39;./td[9]/text()&#39;)).strip()
16 }
17 #print(item)
18 try:
19 with open(&#39;./law.csv&#39;, &#39;a&#39;, encoding=&#39;utf_8_sig&#39;, newline=&#39;&#39;) as fp:
20 # &#39;a&#39;为追加模式(添加)
21 # utf_8_sig格式导出csv不乱码
22 fieldnames = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;,&#39;f&#39;,&#39;g&#39;,&#39;h&#39;,&#39;i&#39;]
23 writer = csv.DictWriter(fp,fieldnames)
24 writer.writerow(item)
25 except Exception:
26 print(traceback.print_exc()) #代替print e 来输出详细的异常信息
27 except Exception:
28 print(traceback.print_exc())
  最后遍历页数,调用函数。OK完成!
  1 for page in range(1,5): #这里设置想要爬取的页数
2 html = get_page(page)
3 #print(html)
4 print("第" + str(page) + "页提取完成")
  我们来看看最终的效果:
  
  二
  硒
  渴望学习的朋友可能还想看看Selenium是如何爬取AJAX动态加载的网页的。J哥自然会满足你的好奇心。于是赶紧新建了一个py文件,准备趁势而上,用Selenium把这个网站爬下来。
  首先,导入相关库。
  1from lxml import etree
2import time
3from selenium import webdriver
4from selenium. webdriver.support.wait import WebDriverWait
5from selenium.webdriver.support import expected_conditions as EC
6from selenium.webdriver.common.by import By
  然后,使用chromedriver驱动打开这个网站。
  1def main():
2 # 爬取首页url
3 url = "http://www.hshfy.sh.cn/shfy/gw ... ot%3B
4 # 定义谷歌webdriver
5 driver = webdriver.Chrome(&#39;./chromedriver&#39;)
6 driver.maximize_window() # 将浏览器最大化
7 driver.get(url)
  所以,我惊讶地发现报告了一个错误。以CET-6英语的词汇储备,J哥居然听懂了!可能是我的驱动和浏览器版本不匹配,只支持79版本的浏览器。
  J兄很郁闷,因为我以前用Selenium从来没有遇到过这种问题。J哥不甘心,打开谷歌浏览器查看版本号。
  
  我失去了它!都更新到了81版!遇到这种情况,请好奇的朋友等待J哥设置浏览器自动更新并重新下载最新驱动,下次再来听听Selenium爬虫吧。记得关注本公众号,不要错过精彩哦~
  综上所述,对于网络爬虫的AJAX动态加载,一般有两种方式:解析接口;硒。J兄推荐解析接口的方式。如果是解析json数据,最好是爬取。如果你不知道如何使用Selenium,让我们使用Selenium。

java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)

网站优化优采云 发表了文章 • 0 个评论 • 70 次浏览 • 2021-11-29 08:18 • 来自相关话题

  java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)
  下面的例子展示了如何使用 Jsoup 进行分析。在这种情况下,将获得博客花园首页的标题和第一页的博客列表文章。
  
  请看代码(在前面代码的基础上进行操作,如果不知道如何使用httpclient,请跳转页面阅读):
  引入依赖
  
org.jsoup
jsoup
1.12.1
  实现代码。在实现代码之前,先分析一下html结构。标题不用说了,文章列表呢?按浏览器的F12,查看页面元素的源代码。你会发现list是一个大div,id="post_list",每篇文章文章都是一个小div,class="post_item"
  
  然后就可以开始代码了,Jsoup的核心代码如下(整体源码会在文章的最后给出):
  /**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}
  根据上面的代码,你会发现我通过Jsoup.parse(String html)方法解析httpclient获取到的html内容获取Document,然后文档可以通过两种方式获取它的子元素:像js一样,它可以通过 getElementXXXX 获取。像 jquery 选择器一样传递 select() 方法。无论哪种方式都可以,我个人建议使用 select 方法。对于元素中的属性,比如超链接地址,可以使用 element.attr(String) 方法获取,对于元素的文本内容,可以使用 element.text() 方法获取。
  执行代码,查看结果(不得不感慨博客园的园友真是厉害。从上面对首页html结构的分析,到Jsoup分析的代码的执行,在这次文章)
  
  由于新的文章发布太快,上面的截图和这里的输出有些不同。
  三、Jsoup的其他用法
  我Jsoup除了可以发挥httpclient小哥的工作成果外,还可以自己动手,自己抓取页面,然后自己分析。上面已经展示了分析技巧,下面展示如何自己抓取页面。其实很简单。不同的是我直接拿到文档,不需要通过Jsoup.parse()方法解析。
  
  除了直接访问在线资源,我还可以分析本地资源:
  代码:
  public static void main(String[] args) {
try {
Document document = Jsoup.parse(new File("d://1.html"), "utf-8");
System.out.println(document);
} catch (IOException e) {
e.printStackTrace();
}
}
  四、Jsoup 另一个值得一提的功能
  你一定有过这样的经历。在你页面的文本框中,如果你输入了html元素,保存后页面布局很可能会乱七八糟。如果能过滤一下内容就完美了。
  碰巧我可以用 Jsoup 做到这一点。
  通过 Jsoup.clean 方法,使用白名单进行过滤。结果:
  unsafe: <p>博客园
safe:
  <a rel="nofollow">博客园</a></p>
  五、结论
  通过以上,大家都相信我很厉害了。不仅可以解析HttpClient抓取到的html元素,还可以自己抓取页面dom,还可以加载解析本地保存的html文件。
  另外,我可以通过白名单过滤字符串,过滤掉一些不安全的字符。
  最重要的是,以上所有函数的API调用都比较简单。
  ============华丽的分割线============
  码字不易,喜欢就​​去吧~~
  最后附上案例分析中博客园首页文章列表的完整源码:
  
  
  package httpclient_learn;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class HttpClientTest {

public static void main(String[] args) {
//1.生成httpclient,相当于该打开一个浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
//2.创建get请求,相当于在浏览器地址栏输入 网址
HttpGet request = new HttpGet("https://www.cnblogs.com/");
//设置请求头,将爬虫伪装成浏览器
request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
// HttpHost proxy = new HttpHost("60.13.42.232", 9999);
// RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
// request.setConfig(config);
try {
//3.执行get请求,相当于在输入地址栏后敲回车键
response = httpClient.execute(request);

//4.判断响应状态为200,进行处理
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//5.获取响应内容
HttpEntity httpEntity = response.getEntity();
String html = EntityUtils.toString(httpEntity, "utf-8");
System.out.println(html);

/**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}


} else {
//如果返回状态不是200,比如404(页面不存在)等,根据情况做处理,这里略
System.out.println("返回状态不是200");
System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//6.关闭
HttpClientUtils.closeQuietly(response);
HttpClientUtils.closeQuietly(httpClient);
}
}
}
  查看代码 查看全部

  java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)
  下面的例子展示了如何使用 Jsoup 进行分析。在这种情况下,将获得博客花园首页的标题和第一页的博客列表文章。
  
  请看代码(在前面代码的基础上进行操作,如果不知道如何使用httpclient,请跳转页面阅读):
  引入依赖
  
org.jsoup
jsoup
1.12.1
  实现代码。在实现代码之前,先分析一下html结构。标题不用说了,文章列表呢?按浏览器的F12,查看页面元素的源代码。你会发现list是一个大div,id="post_list",每篇文章文章都是一个小div,class="post_item"
  
  然后就可以开始代码了,Jsoup的核心代码如下(整体源码会在文章的最后给出):
  /**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}
  根据上面的代码,你会发现我通过Jsoup.parse(String html)方法解析httpclient获取到的html内容获取Document,然后文档可以通过两种方式获取它的子元素:像js一样,它可以通过 getElementXXXX 获取。像 jquery 选择器一样传递 select() 方法。无论哪种方式都可以,我个人建议使用 select 方法。对于元素中的属性,比如超链接地址,可以使用 element.attr(String) 方法获取,对于元素的文本内容,可以使用 element.text() 方法获取。
  执行代码,查看结果(不得不感慨博客园的园友真是厉害。从上面对首页html结构的分析,到Jsoup分析的代码的执行,在这次文章)
  
  由于新的文章发布太快,上面的截图和这里的输出有些不同。
  三、Jsoup的其他用法
  我Jsoup除了可以发挥httpclient小哥的工作成果外,还可以自己动手,自己抓取页面,然后自己分析。上面已经展示了分析技巧,下面展示如何自己抓取页面。其实很简单。不同的是我直接拿到文档,不需要通过Jsoup.parse()方法解析。
  
  除了直接访问在线资源,我还可以分析本地资源:
  代码:
  public static void main(String[] args) {
try {
Document document = Jsoup.parse(new File("d://1.html"), "utf-8");
System.out.println(document);
} catch (IOException e) {
e.printStackTrace();
}
}
  四、Jsoup 另一个值得一提的功能
  你一定有过这样的经历。在你页面的文本框中,如果你输入了html元素,保存后页面布局很可能会乱七八糟。如果能过滤一下内容就完美了。
  碰巧我可以用 Jsoup 做到这一点。
  通过 Jsoup.clean 方法,使用白名单进行过滤。结果:
  unsafe: <p>博客园
safe:
  <a rel="nofollow">博客园</a></p>
  五、结论
  通过以上,大家都相信我很厉害了。不仅可以解析HttpClient抓取到的html元素,还可以自己抓取页面dom,还可以加载解析本地保存的html文件。
  另外,我可以通过白名单过滤字符串,过滤掉一些不安全的字符。
  最重要的是,以上所有函数的API调用都比较简单。
  ============华丽的分割线============
  码字不易,喜欢就​​去吧~~
  最后附上案例分析中博客园首页文章列表的完整源码:
  
  
  package httpclient_learn;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class HttpClientTest {

public static void main(String[] args) {
//1.生成httpclient,相当于该打开一个浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
//2.创建get请求,相当于在浏览器地址栏输入 网址
HttpGet request = new HttpGet("https://www.cnblogs.com/";);
//设置请求头,将爬虫伪装成浏览器
request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
// HttpHost proxy = new HttpHost("60.13.42.232", 9999);
// RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
// request.setConfig(config);
try {
//3.执行get请求,相当于在输入地址栏后敲回车键
response = httpClient.execute(request);

//4.判断响应状态为200,进行处理
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//5.获取响应内容
HttpEntity httpEntity = response.getEntity();
String html = EntityUtils.toString(httpEntity, "utf-8");
System.out.println(html);

/**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}


} else {
//如果返回状态不是200,比如404(页面不存在)等,根据情况做处理,这里略
System.out.println("返回状态不是200");
System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//6.关闭
HttpClientUtils.closeQuietly(response);
HttpClientUtils.closeQuietly(httpClient);
}
}
}
  查看代码

java爬虫抓取动态网页(Python却是最常用的,你知道为什么吗?和python教程入门学习)

网站优化优采云 发表了文章 • 0 个评论 • 54 次浏览 • 2021-12-25 03:12 • 来自相关话题

  java爬虫抓取动态网页(Python却是最常用的,你知道为什么吗?和python教程入门学习)
  说起网络爬虫,相信大家都不陌生。爬虫可以爬取某个网站或者某个应用的内容,提取有用的价值信息。很多编程语言都可以用来实现爬虫,但最常用的是Python。你知道为什么吗?一起来看看python教程的入门学习吧~
  
  与C、Python 和C 相比Python 是C 开发的语言,但在使用方面,Python 的库完整方便,而C 语言则麻烦很多。要实现同样的功能,Python 只需要 10 行代码,而 C 语言可能需要 100 行甚至更多。但在运行速度方面,C语言更胜一筹。
  对比Python和Java,Java有很多解析器,对网页解析的支持非常好。Java 也有爬虫相关的库,但没有 Python 多。不过就爬虫的效果而言,Java和Python都可以做到,只是工程量不同,实现的方式也不同。如果需要处理复杂的网页,解析网页内容生成结构化数据,或者微调网页内容,java会更合适。
  Python与其他语言没有本质区别,优势在于Python语法简单明了,开发效率高。另外,python语言的流行还有几个原因:
  1. 抓取网页的界面简单;
  与其他动态脚本语言相比,Python 提供了更完善的访问网页文档的 API;与其他静态编程语言相比,Python 拥有更简洁的网页抓取界面。
  2.强大的第三方库
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这时候就需要模拟User Agent的行为来构造合适的请求,比如模拟用户登录,模拟Session/Cookie的存储和设置。Python 中有出色的第三方包可以帮助您完成它,例如 Requests 或 Mechanize。
  3.数据处理快捷方便
  抓取到的网页通常需要进行处理,例如过滤Html标签、提取文本等。Python 的 Beautiful Soup 提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。其实很多语言和工具都可以做到以上功能,但是Python可以做到最快最干净。
  如何领取python福利教程:
  1、喜欢+评论(勾选“同时转发”)
  2、关注小编。并回复私信关键词[19]
  (一定要发私信哦~点我头像看私信按钮) 查看全部

  java爬虫抓取动态网页(Python却是最常用的,你知道为什么吗?和python教程入门学习)
  说起网络爬虫,相信大家都不陌生。爬虫可以爬取某个网站或者某个应用的内容,提取有用的价值信息。很多编程语言都可以用来实现爬虫,但最常用的是Python。你知道为什么吗?一起来看看python教程的入门学习吧~
  
  与C、Python 和C 相比Python 是C 开发的语言,但在使用方面,Python 的库完整方便,而C 语言则麻烦很多。要实现同样的功能,Python 只需要 10 行代码,而 C 语言可能需要 100 行甚至更多。但在运行速度方面,C语言更胜一筹。
  对比Python和Java,Java有很多解析器,对网页解析的支持非常好。Java 也有爬虫相关的库,但没有 Python 多。不过就爬虫的效果而言,Java和Python都可以做到,只是工程量不同,实现的方式也不同。如果需要处理复杂的网页,解析网页内容生成结构化数据,或者微调网页内容,java会更合适。
  Python与其他语言没有本质区别,优势在于Python语法简单明了,开发效率高。另外,python语言的流行还有几个原因:
  1. 抓取网页的界面简单;
  与其他动态脚本语言相比,Python 提供了更完善的访问网页文档的 API;与其他静态编程语言相比,Python 拥有更简洁的网页抓取界面。
  2.强大的第三方库
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这时候就需要模拟User Agent的行为来构造合适的请求,比如模拟用户登录,模拟Session/Cookie的存储和设置。Python 中有出色的第三方包可以帮助您完成它,例如 Requests 或 Mechanize。
  3.数据处理快捷方便
  抓取到的网页通常需要进行处理,例如过滤Html标签、提取文本等。Python 的 Beautiful Soup 提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。其实很多语言和工具都可以做到以上功能,但是Python可以做到最快最干净。
  如何领取python福利教程:
  1、喜欢+评论(勾选“同时转发”)
  2、关注小编。并回复私信关键词[19]
  (一定要发私信哦~点我头像看私信按钮)

java爬虫抓取动态网页( 动态网页爬虫技术一之API请求法安装selenium模块下载(组图))

网站优化优采云 发表了文章 • 0 个评论 • 76 次浏览 • 2021-12-25 02:04 • 来自相关话题

  java爬虫抓取动态网页(
动态网页爬虫技术一之API请求法安装selenium模块下载(组图))
  
  在本次讲座中,我将解释一个稍微复杂一些的爬虫,即动态网页的爬虫。
  动态网页技术介绍
  动态网络爬虫技术一API请求方式
  动态网络爬虫技术二模拟浏览器方法
  安装 selenium 模块下载
  谷歌浏览器驱动安装
  ChromeDriver以某宝的松鼠店为例,抓取“坚果炒货”的产品名称、价格、销量和评论数
  课后作业
  关于作者
  动态网页技术介绍
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。
  值得强调的是,不要将动态网页与页面内容是否动态混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果无关。动态网页也可以是纯文本内容,也可以收录各种动画内容。这些只是网页的细节。内容的呈现形式,无论网页是否有动态效果,只要是使用动态网站技术生成的网页,都可以称为动态网页。(解释来源:百度百科-“动态网页”,如果链接失败请访问:%E5%8A%A8%E6%80%81%E7%BD%91%E9%A1%B5/6327050?fr=aladdin )
  
  互联网每天都在蓬勃发展。数以万计的网络平台如雨后春笋般涌现。不同的平台有不同的权限和偏好,不同的用户可以推出不同的个性化内容。传统的静态网页似乎早已无法满足社会的需求。于是,动态网页技术应运而生。当然,在对网页加载速度要求越来越高的今天,异步加载已经成为很多大型网站的首选。比如各大电商平台、知识型网站、社交平台等,都广泛采用了异步加载的动态技术。简单的说就是一些随着时间和要求而变化的内容,比如某宝的商品价格、评论、
  对于这种类型的动态页面,如果我们使用前面提到的静态网页的爬虫方法,可能得不到任何结果,因为异步加载的内容所在的位置多是请求内容的一段JS代码。在一定的触发操作下,这些JS代码开始工作,从数据库中提取出相应的数据,放置在网页框架中的相应位置,从而最终拼接成一个我们可以看到的完整页面。
  动态网络爬虫技术一API请求方式
  看似比较复杂的操作,看似给我们的爬虫带来了很大的麻烦,但实际上它们也可能给我们带来很大的便利。我们只需要找到JS请求的API,并按照一定的要求发送带有有效参数的请求就可以得到最干净的数据,而不是像以前那样从嵌套的HTML代码中慢慢解析我们想要的。所需数据。
  这里我们以上面提到的豆瓣电影(如果链接失败,请访问:#!type=movie&amp;tag=%E7%83%AD%E9%97%A8&amp;sort=recommend&amp;page_limit=20&amp;page_start=0)为例制作一个分析,提取豆瓣前100部电影的名字和评分以及它们的地址。
  
  这是近期热门电影按人气排序的截图。每个月都有不同的新电影上映。每部电影每天都会以口碑效应呈现不同的人气排名。如果这个页面是静态网页,那么豆瓣的程序员是不是很辛苦,每天都要上网修改这个页面。因此,我们可以大胆猜测这是一个动态页面。但仅仅猜测是行不通的,我们必须证明这一点。这里我们将使用第二讲中提到的谷歌开发者工具。按F12或在网页空白处右击选择勾选(N),或按键盘上的组合键Ctrl + Shift + I来召唤我们的神器。如下所示:
  
  今天我们不再使用左上角的鼠标按钮,而是使用红色框中的网络。下面是网页加载的所有文件,如下图所示:
  
  如果下面没有结果,您需要在打开 Google Developer Tools 的同时刷新网页。
  
  如上图所示,我们可以点击上方小红框中的“XHR”按钮,过滤掉这个网页中异步加载的内容。至于哪个是我们想要的,这是个问题。看左边的地址,我们似乎没有看到线索,所以我们一一点击。. . 经过枚举,我们发现第三个就是我们想要的,其内容如下图所示:
  
  我们可以看到这个链接中收录的内容是以JSON格式显示的。这时候我们有了一个大致的思路,就是用requests模块下载这个链接的内容,然后用Python的json模块。解析。
  然而,这似乎是一页内容。计数中只有 20 部电影。我们想要的是前 100 部电影。我们应该做什么?
  没办法,毕竟是动态网页,可以根据请求更改内容,这里也没有登录操作,打开网页就可以看到,那我们能不能把网址改成进入下一页甚至下一页?页面的内容是什么?当然可以,不然我就写不下去了!
  让我们仔细看看这个 URL 中传递的参数:
  
  这时候我们可能不知道这五个参数是什么,但是我们可以找到规则,所以现在回到原来的网页,点击页面底部的“加载更多”,然后回到开发者工具,哇,多了一个网址,和刚才说的一样长,内容也一样长:
  
  此 URL 还传递五个参数:
  
  唯一的区别是名为“page_start”的关键字的值发生了变化。一个简单的翻译可能是页面的开头。看上面的“page_limit”,大概是指页数限制。查看右侧的响应内容。这个页面已经过了20个条目,也就是说“page_limit”是一个页面的条目数量限制,也就是20。这个数据不变,而“page_start”是在这个页面的条目数量这个页面的开头,那我们要不要把这个“page_start”改一下就可以得到下面的内容了?是的。
  老规矩,先写个代码
  # -*- coding: utf-8 -*-
import requests
import jsonfor i in range(5):
page_start = str(i * 20) # 注释1
url = &#39;https://movie.douban.com/j/sea ... 39%3B + page_start # 注释2
headers = {&#39;User-Agent&#39;: &#39;Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36&#39;
}
response = requests.get(url=url, headers=headers, verify=False)
content = response.content.decode()
content_list = json.loads(content)[&#39;subjects&#39;] # 注释3for item in content_list: # 注释4
title = item[&#39;title&#39;] #注释5
rate = item[&#39;rate&#39;] # 注释6
link = item[&#39;url&#39;] # 注释7
print(title, rate, link)
  
  最后,可以使用标准输入流写入txt文件,也可以使用xlwt模块写入EXCEL,也可以使用pymysql模块写入Mysql数据库,具体方法免费,请自行百度你自己。
  至此,这种通过查找API并传递有效参数来重放API的方法已经介绍给大家了。这是一个非常通用的方法。它可以在很多网站中使用,并且速度非常快,并且具有最精简的结果。.
  动态网络爬虫技术二模拟浏览器方法
  虽然我们上面提到的API请求方式简单易用,速度快,但并不是所有的网站都会使用这种异步加载的方式来实现网站,有的网站会采取反爬虫措施来对付爬虫,比如常见的验证码。验证码虽然主要是用来防止CSRF攻击,但也有网站用来对付爬虫,比如某宝。这时候,我们将介绍另一个神器,Python 的 Selenium 模块。
  Selenium 是一种用于 Web 应用程序测试的工具。Selenium 测试直接在浏览器中运行,就像真实用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11), Mozilla Firefox, Safari, Google Chrome, Opera等。本工具的主要功能包括:测试与浏览器的兼容性-测试您的应用程序可以在不同的浏览器和操作系统上运行良好测试系统功能-创建回归测试以验证软件功能和用户需求支持自动记录动作和自动生成.Net、Java、Perl等多种语言的测试脚本。 (说明来自:百度百科-《硒》,链接失效请点击)
  简单来说,Selenium 是一个主要用于自动化测试的工具。可以配合浏览器驱动运行在各个浏览器中,根据代码自动模拟人为操作,获取或控制网页元素。当然,Selenium 不是 Python 的产品,而是一个独立的项目。Python 提供对 Selenium 的支持。(您可以自行访问Selenium的主页,如果链接无效,请点击)
  安装硒模块
  要使用像Selenium这样的第三方工具,我们必须先安装它,这里仍然使用pip工具。以管理员权限运行命令行,输入pip install selenium。稍等片刻,即可完成安装。如果觉得连接官方pypi镜像的网络慢,可以使用国内豆瓣的镜像源,pip install selenium -i,加上这个-i参数和豆瓣pypi镜像的地址就够了。如果要默认使用豆瓣镜像源,请百度修改方法。
  下载谷歌浏览器驱动程序
  安装成功后,我们需要安装下一个必备的东西,浏览器驱动。前面说过,selenium需要配合浏览器驱动,所以我们以安装Google Chrome Driver为例。
  首先,我们需要检查我们的谷歌浏览器版本。这可以在谷歌的“帮助”中查看。具体方法是打开Chrome,点击右上角的三个点状按钮,然后在弹出的菜单中选择帮助。(E) -&gt; 关于谷歌浏览器 (G) 如下图:
  
  笔者浏览器更新到最新版本63,老版本操作方法大致相同。
  点击信息上的开关后,我们可以看到当前的Chrome版本。下图是一个例子:
  
  Chrome 是在不断升级的,所以相应的驱动也要不断的升级,适配 Chrome 的版本。这里需要找到对应的ChromeDriver版本映射,推荐一个持续更新的CSDN博客(如果链接失效请点击:),根据版本映射表,下载对应版本的ChromeDriver,下载地址1()(如果链接失效,请访问:),下载地址2()(链接失效请访问:)。
  安装 ChromeDriver
  这里需要配置环境变量。如第一讲所述,为“Path”添加一行值。
  首先,我们需要找到Chrome的安装位置。最简单的方法是在桌面找到谷歌浏览器的快捷方式,右击选择“打开文件位置”打开。比如我这里打开的路径是C:\Program Files(x86)\Google\Chrome\Application,然后我会在Path中添加这个路径。然后,我们需要将下载的ChromeDriver解压到exe程序,将单独的exe程序复制到刚才的路径下,如下图:
  
  至此,ChromeDriver 安装完成。我们可以在命令行输入命令python进入python交互环境进行测试,如下图所示:
  
  如果你的谷歌浏览器自动打开并跳转到百度主页,那么恭喜~
  以某宝的松鼠店为例,爬取“坚果炒货”的产品名称、价格、销量和评论数
  此页面的 URL 是:#TmshopSrchNav
  老规矩,先放一段代码:
  # -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Chrome() # 注释1
url = &#39;https://sanzhisongshu.tmall.co ... 39%3B
driver.maximize_window() # 注释2
driver.get(url) # 注释3
dl_list = driver.find_elements_by_class_name(&#39;item&#39;) # 注释4
for dl in dl_list:
name = dl.find_element_by_css_selector("[class=&#39;item-name J_TGoldData&#39;]").text # 注释5
price = dl.find_element_by_class_name(&#39;cprice-area&#39;).text # 注释6
sale = dl.find_element_by_class_name(&#39;sale-area&#39;).text # 注释7
comment = dl.find_element_by_xpath(&#39;//*[@id="J_ShopSearchResult"]/div/div[3]/div[1]/dl[1]/dd[2]/div/h4/a/span&#39;).text # 注释8
print(name, price, sale, comment)
driver.close() # 注释9
  
  XPath 是 XML 路径语言,它是一种用于确定 XML(标准通用标记语言的子集)文档某个部分的位置的语言。XPath 基于 XML 树结构,具有不同类型的节点,包括元素节点、属性节点和文本节点,提供在数据结构树中查找节点的能力。最初,XPath 的初衷是将其用作 XPointer 和 XSLT 之间的通用语法模型。但是 XPath 很快就被开发人员采用为一种小型查询语言。(说明来自:百度百科-“XPath”,如果链接失败,请访问:)
  
  这个例子的最终结果如下:
  
  大家依然可以自由选择数据的存储方式。
  这里需要注意的是,使用selenium进行数据爬取可能比之前的API请求方式慢很多。打开相应的窗口后,窗口中可能长时间没有动作,但这不一定是错误或程序卡住的迹象,也可能是程序在疯狂搜索网页元素。在此过程中,如果您不确定是否有错误,请不要进行其他操作,以免有时会导致元素失去焦点而导致莫名其妙的错误。
  当然,硒的作用远不止这些。它可以模拟几乎人在网页上可以做出的行为,包括点击、打字等行为。这个比较适合一些网站填写验证码的情况,大家可以自行寻找更多有趣的内容。本次讲座到此结束。感谢您的耐心阅读。
  课后作业
  这里有两个小作业给大家,有兴趣的可以自己测试一下。
  请使用API​​请求方式在QQ音乐上查找付费下载歌曲,无需登录账号即可下载歌曲。请用selenium爬取知乎首页热点话题或回答100个话题。
  关于作者
  作者是即将毕业的大四,自学爬虫,作为多个爬虫项目的主要开发者,对各种爬虫有一定的了解和项目经验,目前正在自学分布式爬虫的内容,以后会继续为大家关注更新。同时作者也是一位狂热的信息安全爱好者。谢谢你的支持。 查看全部

  java爬虫抓取动态网页(
动态网页爬虫技术一之API请求法安装selenium模块下载(组图))
  
  在本次讲座中,我将解释一个稍微复杂一些的爬虫,即动态网页的爬虫。
  动态网页技术介绍
  动态网络爬虫技术一API请求方式
  动态网络爬虫技术二模拟浏览器方法
  安装 selenium 模块下载
  谷歌浏览器驱动安装
  ChromeDriver以某宝的松鼠店为例,抓取“坚果炒货”的产品名称、价格、销量和评论数
  课后作业
  关于作者
  动态网页技术介绍
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。
  值得强调的是,不要将动态网页与页面内容是否动态混淆。这里所说的动态网页与网页上的各种动画、滚动字幕等视觉动态效果无关。动态网页也可以是纯文本内容,也可以收录各种动画内容。这些只是网页的细节。内容的呈现形式,无论网页是否有动态效果,只要是使用动态网站技术生成的网页,都可以称为动态网页。(解释来源:百度百科-“动态网页”,如果链接失败请访问:%E5%8A%A8%E6%80%81%E7%BD%91%E9%A1%B5/6327050?fr=aladdin )
  
  互联网每天都在蓬勃发展。数以万计的网络平台如雨后春笋般涌现。不同的平台有不同的权限和偏好,不同的用户可以推出不同的个性化内容。传统的静态网页似乎早已无法满足社会的需求。于是,动态网页技术应运而生。当然,在对网页加载速度要求越来越高的今天,异步加载已经成为很多大型网站的首选。比如各大电商平台、知识型网站、社交平台等,都广泛采用了异步加载的动态技术。简单的说就是一些随着时间和要求而变化的内容,比如某宝的商品价格、评论、
  对于这种类型的动态页面,如果我们使用前面提到的静态网页的爬虫方法,可能得不到任何结果,因为异步加载的内容所在的位置多是请求内容的一段JS代码。在一定的触发操作下,这些JS代码开始工作,从数据库中提取出相应的数据,放置在网页框架中的相应位置,从而最终拼接成一个我们可以看到的完整页面。
  动态网络爬虫技术一API请求方式
  看似比较复杂的操作,看似给我们的爬虫带来了很大的麻烦,但实际上它们也可能给我们带来很大的便利。我们只需要找到JS请求的API,并按照一定的要求发送带有有效参数的请求就可以得到最干净的数据,而不是像以前那样从嵌套的HTML代码中慢慢解析我们想要的。所需数据。
  这里我们以上面提到的豆瓣电影(如果链接失败,请访问:#!type=movie&amp;tag=%E7%83%AD%E9%97%A8&amp;sort=recommend&amp;page_limit=20&amp;page_start=0)为例制作一个分析,提取豆瓣前100部电影的名字和评分以及它们的地址。
  
  这是近期热门电影按人气排序的截图。每个月都有不同的新电影上映。每部电影每天都会以口碑效应呈现不同的人气排名。如果这个页面是静态网页,那么豆瓣的程序员是不是很辛苦,每天都要上网修改这个页面。因此,我们可以大胆猜测这是一个动态页面。但仅仅猜测是行不通的,我们必须证明这一点。这里我们将使用第二讲中提到的谷歌开发者工具。按F12或在网页空白处右击选择勾选(N),或按键盘上的组合键Ctrl + Shift + I来召唤我们的神器。如下所示:
  
  今天我们不再使用左上角的鼠标按钮,而是使用红色框中的网络。下面是网页加载的所有文件,如下图所示:
  
  如果下面没有结果,您需要在打开 Google Developer Tools 的同时刷新网页。
  
  如上图所示,我们可以点击上方小红框中的“XHR”按钮,过滤掉这个网页中异步加载的内容。至于哪个是我们想要的,这是个问题。看左边的地址,我们似乎没有看到线索,所以我们一一点击。. . 经过枚举,我们发现第三个就是我们想要的,其内容如下图所示:
  
  我们可以看到这个链接中收录的内容是以JSON格式显示的。这时候我们有了一个大致的思路,就是用requests模块下载这个链接的内容,然后用Python的json模块。解析。
  然而,这似乎是一页内容。计数中只有 20 部电影。我们想要的是前 100 部电影。我们应该做什么?
  没办法,毕竟是动态网页,可以根据请求更改内容,这里也没有登录操作,打开网页就可以看到,那我们能不能把网址改成进入下一页甚至下一页?页面的内容是什么?当然可以,不然我就写不下去了!
  让我们仔细看看这个 URL 中传递的参数:
  
  这时候我们可能不知道这五个参数是什么,但是我们可以找到规则,所以现在回到原来的网页,点击页面底部的“加载更多”,然后回到开发者工具,哇,多了一个网址,和刚才说的一样长,内容也一样长:
  
  此 URL 还传递五个参数:
  
  唯一的区别是名为“page_start”的关键字的值发生了变化。一个简单的翻译可能是页面的开头。看上面的“page_limit”,大概是指页数限制。查看右侧的响应内容。这个页面已经过了20个条目,也就是说“page_limit”是一个页面的条目数量限制,也就是20。这个数据不变,而“page_start”是在这个页面的条目数量这个页面的开头,那我们要不要把这个“page_start”改一下就可以得到下面的内容了?是的。
  老规矩,先写个代码
  # -*- coding: utf-8 -*-
import requests
import jsonfor i in range(5):
page_start = str(i * 20) # 注释1
url = &#39;https://movie.douban.com/j/sea ... 39%3B + page_start # 注释2
headers = {&#39;User-Agent&#39;: &#39;Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36&#39;
}
response = requests.get(url=url, headers=headers, verify=False)
content = response.content.decode()
content_list = json.loads(content)[&#39;subjects&#39;] # 注释3for item in content_list: # 注释4
title = item[&#39;title&#39;] #注释5
rate = item[&#39;rate&#39;] # 注释6
link = item[&#39;url&#39;] # 注释7
print(title, rate, link)
  
  最后,可以使用标准输入流写入txt文件,也可以使用xlwt模块写入EXCEL,也可以使用pymysql模块写入Mysql数据库,具体方法免费,请自行百度你自己。
  至此,这种通过查找API并传递有效参数来重放API的方法已经介绍给大家了。这是一个非常通用的方法。它可以在很多网站中使用,并且速度非常快,并且具有最精简的结果。.
  动态网络爬虫技术二模拟浏览器方法
  虽然我们上面提到的API请求方式简单易用,速度快,但并不是所有的网站都会使用这种异步加载的方式来实现网站,有的网站会采取反爬虫措施来对付爬虫,比如常见的验证码。验证码虽然主要是用来防止CSRF攻击,但也有网站用来对付爬虫,比如某宝。这时候,我们将介绍另一个神器,Python 的 Selenium 模块。
  Selenium 是一种用于 Web 应用程序测试的工具。Selenium 测试直接在浏览器中运行,就像真实用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11), Mozilla Firefox, Safari, Google Chrome, Opera等。本工具的主要功能包括:测试与浏览器的兼容性-测试您的应用程序可以在不同的浏览器和操作系统上运行良好测试系统功能-创建回归测试以验证软件功能和用户需求支持自动记录动作和自动生成.Net、Java、Perl等多种语言的测试脚本。 (说明来自:百度百科-《硒》,链接失效请点击)
  简单来说,Selenium 是一个主要用于自动化测试的工具。可以配合浏览器驱动运行在各个浏览器中,根据代码自动模拟人为操作,获取或控制网页元素。当然,Selenium 不是 Python 的产品,而是一个独立的项目。Python 提供对 Selenium 的支持。(您可以自行访问Selenium的主页,如果链接无效,请点击)
  安装硒模块
  要使用像Selenium这样的第三方工具,我们必须先安装它,这里仍然使用pip工具。以管理员权限运行命令行,输入pip install selenium。稍等片刻,即可完成安装。如果觉得连接官方pypi镜像的网络慢,可以使用国内豆瓣的镜像源,pip install selenium -i,加上这个-i参数和豆瓣pypi镜像的地址就够了。如果要默认使用豆瓣镜像源,请百度修改方法。
  下载谷歌浏览器驱动程序
  安装成功后,我们需要安装下一个必备的东西,浏览器驱动。前面说过,selenium需要配合浏览器驱动,所以我们以安装Google Chrome Driver为例。
  首先,我们需要检查我们的谷歌浏览器版本。这可以在谷歌的“帮助”中查看。具体方法是打开Chrome,点击右上角的三个点状按钮,然后在弹出的菜单中选择帮助。(E) -&gt; 关于谷歌浏览器 (G) 如下图:
  
  笔者浏览器更新到最新版本63,老版本操作方法大致相同。
  点击信息上的开关后,我们可以看到当前的Chrome版本。下图是一个例子:
  
  Chrome 是在不断升级的,所以相应的驱动也要不断的升级,适配 Chrome 的版本。这里需要找到对应的ChromeDriver版本映射,推荐一个持续更新的CSDN博客(如果链接失效请点击:),根据版本映射表,下载对应版本的ChromeDriver,下载地址1()(如果链接失效,请访问:),下载地址2()(链接失效请访问:)。
  安装 ChromeDriver
  这里需要配置环境变量。如第一讲所述,为“Path”添加一行值。
  首先,我们需要找到Chrome的安装位置。最简单的方法是在桌面找到谷歌浏览器的快捷方式,右击选择“打开文件位置”打开。比如我这里打开的路径是C:\Program Files(x86)\Google\Chrome\Application,然后我会在Path中添加这个路径。然后,我们需要将下载的ChromeDriver解压到exe程序,将单独的exe程序复制到刚才的路径下,如下图:
  
  至此,ChromeDriver 安装完成。我们可以在命令行输入命令python进入python交互环境进行测试,如下图所示:
  
  如果你的谷歌浏览器自动打开并跳转到百度主页,那么恭喜~
  以某宝的松鼠店为例,爬取“坚果炒货”的产品名称、价格、销量和评论数
  此页面的 URL 是:#TmshopSrchNav
  老规矩,先放一段代码:
  # -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Chrome() # 注释1
url = &#39;https://sanzhisongshu.tmall.co ... 39%3B
driver.maximize_window() # 注释2
driver.get(url) # 注释3
dl_list = driver.find_elements_by_class_name(&#39;item&#39;) # 注释4
for dl in dl_list:
name = dl.find_element_by_css_selector("[class=&#39;item-name J_TGoldData&#39;]").text # 注释5
price = dl.find_element_by_class_name(&#39;cprice-area&#39;).text # 注释6
sale = dl.find_element_by_class_name(&#39;sale-area&#39;).text # 注释7
comment = dl.find_element_by_xpath(&#39;//*[@id="J_ShopSearchResult"]/div/div[3]/div[1]/dl[1]/dd[2]/div/h4/a/span&#39;).text # 注释8
print(name, price, sale, comment)
driver.close() # 注释9
  
  XPath 是 XML 路径语言,它是一种用于确定 XML(标准通用标记语言的子集)文档某个部分的位置的语言。XPath 基于 XML 树结构,具有不同类型的节点,包括元素节点、属性节点和文本节点,提供在数据结构树中查找节点的能力。最初,XPath 的初衷是将其用作 XPointer 和 XSLT 之间的通用语法模型。但是 XPath 很快就被开发人员采用为一种小型查询语言。(说明来自:百度百科-“XPath”,如果链接失败,请访问:)
  
  这个例子的最终结果如下:
  
  大家依然可以自由选择数据的存储方式。
  这里需要注意的是,使用selenium进行数据爬取可能比之前的API请求方式慢很多。打开相应的窗口后,窗口中可能长时间没有动作,但这不一定是错误或程序卡住的迹象,也可能是程序在疯狂搜索网页元素。在此过程中,如果您不确定是否有错误,请不要进行其他操作,以免有时会导致元素失去焦点而导致莫名其妙的错误。
  当然,硒的作用远不止这些。它可以模拟几乎人在网页上可以做出的行为,包括点击、打字等行为。这个比较适合一些网站填写验证码的情况,大家可以自行寻找更多有趣的内容。本次讲座到此结束。感谢您的耐心阅读。
  课后作业
  这里有两个小作业给大家,有兴趣的可以自己测试一下。
  请使用API​​请求方式在QQ音乐上查找付费下载歌曲,无需登录账号即可下载歌曲。请用selenium爬取知乎首页热点话题或回答100个话题。
  关于作者
  作者是即将毕业的大四,自学爬虫,作为多个爬虫项目的主要开发者,对各种爬虫有一定的了解和项目经验,目前正在自学分布式爬虫的内容,以后会继续为大家关注更新。同时作者也是一位狂热的信息安全爱好者。谢谢你的支持。

java爬虫抓取动态网页(Java爬虫使用WebMagic框架介绍(一)_Java(图) )

网站优化优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-25 02:01 • 来自相关话题

  java爬虫抓取动态网页(Java爬虫使用WebMagic框架介绍(一)_Java(图)
)
  最近如果需要用Java写爬虫,就去学习Java爬虫了。因为之前学过Scrapy框架,所以学Java的爬虫使用的是基于Scrapy框架开发的WebMagic框架。有兴趣的可以去看看操作文档:
  这个框架是中国人开发的,所以文档都是中文的,简单易懂。
  引入WebMagic框架的方法在操作文档里,这里就不解释了(建议阅读之前先阅读操作文档文章。我导入jar包使用)
  我用的版本是0.7.3。
  
  本项目使用webmagic框架抓取网易云播放列表,并将抓取到的内容存入mysql。这个演示之前已经用 Python 实现过。有兴趣的可以看看我之前的文章文章
  webmagic的各个模块不再赘述,直接说代码实现即可(默认你已经阅读了操作文档)
  首先创建一个Site对象来配置爬虫,包括爬取间隔、重试次数、请求头等。
   private Site site = Site.me().setSleepTime(1000).setRetryTimes(3).addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0");
  然后写过程方法。流程方法是自定义爬虫逻辑的核心部分,这里制定了筛选规则。
  page.putField()方法可以将数据以key:value的形式保存,然后交给pipeline文件处理。
  后面的网站的url与第一页的url相差最后一个值,所以可以使用字符串拼接。
  然后使用 page.addTargetRequest() 方法将后续 URL 添加到抓取序列中。
  (basic是前面定义的静态成员)
  url=";cat=%E5%85%A8%E9%83%A8&amp;limit=35&amp;offset="
<p> public void process(Page page) {
//将数据交给pipeline文件处理
page.putField("name",page.getHtml().xpath("//li/p[@class=dec]/a/text()").all());
page.putField("src",page.getHtml().xpath("//li/p[@class=dec]/a/@href").all());
page.putField("clicknum",page.getHtml().xpath("//li//div[@class=bottom]/span[@class=nb]/text()").all());
page.putField("author",page.getHtml().xpath("//li//a[@class=nm]/text()").all());
page.putField("homepage",page.getHtml().xpath("//li//a[@class=nm]/@href").all());
//连续爬取后续网页
int flag = 35;
String nexturl = null;
for (int i=flag; i 查看全部

  java爬虫抓取动态网页(Java爬虫使用WebMagic框架介绍(一)_Java(图)
)
  最近如果需要用Java写爬虫,就去学习Java爬虫了。因为之前学过Scrapy框架,所以学Java的爬虫使用的是基于Scrapy框架开发的WebMagic框架。有兴趣的可以去看看操作文档:
  这个框架是中国人开发的,所以文档都是中文的,简单易懂。
  引入WebMagic框架的方法在操作文档里,这里就不解释了(建议阅读之前先阅读操作文档文章。我导入jar包使用)
  我用的版本是0.7.3。
  
  本项目使用webmagic框架抓取网易云播放列表,并将抓取到的内容存入mysql。这个演示之前已经用 Python 实现过。有兴趣的可以看看我之前的文章文章
  webmagic的各个模块不再赘述,直接说代码实现即可(默认你已经阅读了操作文档)
  首先创建一个Site对象来配置爬虫,包括爬取间隔、重试次数、请求头等。
   private Site site = Site.me().setSleepTime(1000).setRetryTimes(3).addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0");
  然后写过程方法。流程方法是自定义爬虫逻辑的核心部分,这里制定了筛选规则。
  page.putField()方法可以将数据以key:value的形式保存,然后交给pipeline文件处理。
  后面的网站的url与第一页的url相差最后一个值,所以可以使用字符串拼接。
  然后使用 page.addTargetRequest() 方法将后续 URL 添加到抓取序列中。
  (basic是前面定义的静态成员)
  url=";cat=%E5%85%A8%E9%83%A8&amp;limit=35&amp;offset="
<p> public void process(Page page) {
//将数据交给pipeline文件处理
page.putField("name",page.getHtml().xpath("//li/p[@class=dec]/a/text()").all());
page.putField("src",page.getHtml().xpath("//li/p[@class=dec]/a/@href").all());
page.putField("clicknum",page.getHtml().xpath("//li//div[@class=bottom]/span[@class=nb]/text()").all());
page.putField("author",page.getHtml().xpath("//li//a[@class=nm]/text()").all());
page.putField("homepage",page.getHtml().xpath("//li//a[@class=nm]/@href").all());
//连续爬取后续网页
int flag = 35;
String nexturl = null;
for (int i=flag; i

java爬虫抓取动态网页(完整的抓取示例工程可加群250108697图 )

网站优化优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-24 23:13 • 来自相关话题

  java爬虫抓取动态网页(完整的抓取示例工程可加群250108697图
)
  网站中的图片和网页本质上是一样的。图片和网页的获取本质上是根据url从网站中获取网页/图片的字节数组(byte[]),浏览器根据http响应头中的content-type信息,浏览器决定是否以网页或图片的形式显示资源。
  完整的抓图示例工程可以加入群250108697,在群文件中获取。
  示例中的代码将美食街中的图片爬取到指定文件夹,爬取结果如下图所示:
  
  核心代码:
  import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import cn.edu.hfut.dmic.webcollector.plugin.net.OkHttpRequester;
import cn.edu.hfut.dmic.webcollector.util.ExceptionUtils;
import cn.edu.hfut.dmic.webcollector.util.FileUtils;
import cn.edu.hfut.dmic.webcollector.util.MD5Utils;
import java.io.File;
/**
* WebCollector抓取图片的例子
* @author hu
*/
public class DemoImageCrawler extends BreadthCrawler {
File baseDir = new File("images");
/**
* 构造一个基于伯克利DB的爬虫
* 伯克利DB文件夹为crawlPath,crawlPath中维护了历史URL等信息
* 不同任务不要使用相同的crawlPath
* 两个使用相同crawlPath的爬虫并行爬取会产生错误
*
* @param crawlPath 伯克利DB使用的文件夹
*/
public DemoImageCrawler(String crawlPath) {
super(crawlPath, true);
//只有在autoParse和autoDetectImg都为true的情况下
//爬虫才会自动解析图片链接
getConf().setAutoDetectImg(true);
//如果使用默认的Requester,需要像下面这样设置一下网页大小上限
//否则可能会获得一个不完整的页面
//下面这行将页面大小上限设置为10M
//getConf().setMaxReceiveSize(1024 * 1024 * 10);
//添加种子URL
addSeed("http://www.meishij.net/");
//限定爬取范围
addRegex("http://www.meishij.net/.*");
addRegex("http://images.meishij.net/.*");
addRegex("-.*#.*");
addRegex("-.*\\?.*");
//设置为断点爬取,否则每次开启爬虫都会重新爬取
// demoImageCrawler.setResumable(true);
setThreads(30);
}
@Override
public void visit(Page page, CrawlDatums next) {
//根据http头中的Content-Type信息来判断当前资源是网页还是图片
String contentType = page.contentType();
//根据Content-Type判断是否为图片
if(contentType!=null && contentType.startsWith("image")){
//从Content-Type中获取图片扩展名
String extensionName=contentType.split("/")[1];
try {
byte[] image = page.content();
//根据图片MD5生成文件名
String fileName = String.format("%s.%s",MD5Utils.md5(image), extensionName);
File imageFile = new File(baseDir, fileName);
FileUtils.write(imageFile, image);
System.out.println("保存图片 "+page.url()+" 到 "+ imageFile.getAbsolutePath());
} catch (Exception e) {
ExceptionUtils.fail(e);
}
}
}
public static void main(String[] args) throws Exception {
DemoImageCrawler demoImageCrawler = new DemoImageCrawler("crawl");
demoImageCrawler.setRequester(new OkHttpRequester());
//设置为断点爬取,否则每次开启爬虫都会重新爬取
demoImageCrawler.setResumable(true);
demoImageCrawler.start(3);
}
} 查看全部

  java爬虫抓取动态网页(完整的抓取示例工程可加群250108697图
)
  网站中的图片和网页本质上是一样的。图片和网页的获取本质上是根据url从网站中获取网页/图片的字节数组(byte[]),浏览器根据http响应头中的content-type信息,浏览器决定是否以网页或图片的形式显示资源。
  完整的抓图示例工程可以加入群250108697,在群文件中获取。
  示例中的代码将美食街中的图片爬取到指定文件夹,爬取结果如下图所示:
  
  核心代码:
  import cn.edu.hfut.dmic.webcollector.model.CrawlDatums;
import cn.edu.hfut.dmic.webcollector.model.Page;
import cn.edu.hfut.dmic.webcollector.plugin.berkeley.BreadthCrawler;
import cn.edu.hfut.dmic.webcollector.plugin.net.OkHttpRequester;
import cn.edu.hfut.dmic.webcollector.util.ExceptionUtils;
import cn.edu.hfut.dmic.webcollector.util.FileUtils;
import cn.edu.hfut.dmic.webcollector.util.MD5Utils;
import java.io.File;
/**
* WebCollector抓取图片的例子
* @author hu
*/
public class DemoImageCrawler extends BreadthCrawler {
File baseDir = new File("images");
/**
* 构造一个基于伯克利DB的爬虫
* 伯克利DB文件夹为crawlPath,crawlPath中维护了历史URL等信息
* 不同任务不要使用相同的crawlPath
* 两个使用相同crawlPath的爬虫并行爬取会产生错误
*
* @param crawlPath 伯克利DB使用的文件夹
*/
public DemoImageCrawler(String crawlPath) {
super(crawlPath, true);
//只有在autoParse和autoDetectImg都为true的情况下
//爬虫才会自动解析图片链接
getConf().setAutoDetectImg(true);
//如果使用默认的Requester,需要像下面这样设置一下网页大小上限
//否则可能会获得一个不完整的页面
//下面这行将页面大小上限设置为10M
//getConf().setMaxReceiveSize(1024 * 1024 * 10);
//添加种子URL
addSeed("http://www.meishij.net/";);
//限定爬取范围
addRegex("http://www.meishij.net/.*");
addRegex("http://images.meishij.net/.*");
addRegex("-.*#.*");
addRegex("-.*\\?.*");
//设置为断点爬取,否则每次开启爬虫都会重新爬取
// demoImageCrawler.setResumable(true);
setThreads(30);
}
@Override
public void visit(Page page, CrawlDatums next) {
//根据http头中的Content-Type信息来判断当前资源是网页还是图片
String contentType = page.contentType();
//根据Content-Type判断是否为图片
if(contentType!=null && contentType.startsWith("image")){
//从Content-Type中获取图片扩展名
String extensionName=contentType.split("/")[1];
try {
byte[] image = page.content();
//根据图片MD5生成文件名
String fileName = String.format("%s.%s",MD5Utils.md5(image), extensionName);
File imageFile = new File(baseDir, fileName);
FileUtils.write(imageFile, image);
System.out.println("保存图片 "+page.url()+" 到 "+ imageFile.getAbsolutePath());
} catch (Exception e) {
ExceptionUtils.fail(e);
}
}
}
public static void main(String[] args) throws Exception {
DemoImageCrawler demoImageCrawler = new DemoImageCrawler("crawl");
demoImageCrawler.setRequester(new OkHttpRequester());
//设置为断点爬取,否则每次开启爬虫都会重新爬取
demoImageCrawler.setResumable(true);
demoImageCrawler.start(3);
}
}

java爬虫抓取动态网页( 零基础写Java知乎爬虫之进阶篇抓取一个网站)

网站优化优采云 发表了文章 • 0 个评论 • 75 次浏览 • 2021-12-20 03:01 • 来自相关话题

  java爬虫抓取动态网页(
零基础写Java知乎爬虫之进阶篇抓取一个网站)
  
  搭建开发环境,在项目的Build Path中导入下载的Commons-httpClient3.1.Jar、htmllexer.jar和htmlparser.jar文件。图1. 开发环境搭建HttpClient基础类 该库使用HttpClinet提供了几个支持HTTP访问的类。下面我们通过一些示例代码来熟悉和解释这些类的功能和用途。HttpClient 提供的 HTTP 访问主要通过 GetMethod 类和 PostMethod 类来实现。它们分别对应于HTT
  零基础写Java知乎爬虫进阶篇
  
  说到爬虫,使用Java自带的URLConnection可以实现一些基本的页面爬取功能,但是对于一些更高级的功能,比如重定向处理、去除HTML标签等,单独使用URLConnection是不够的。这里我们可以使用第三方jar包HttpClient。接下来我们用HttpClient写一个简单的爬到百度的demo:import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStr
  从互联网爬取邮箱的Java代码示例
  网络爬虫:其实就是一个用来获取互联网上符合规定规则的数据的程序。包day05; 导入 java.io.BufferedReader; 导入 java.io.IOException; 导入 java.io.InputStreamReader; 导入.URL; 导入java。util.ArrayList; 导入 java.util.List; 导入 java.util.regex.Matcher; 进口
  Java 爬虫实际上抓取了 网站 上的所有链接
  
  前言:在写这篇文章之前,主要看了几个类似的爬虫写法,有的写成队列,感觉不是很直观,有的只有一个请求然后页面分析,没有自动爬行。这也叫爬虫?所以我根据自己的想法写了一个简单的爬虫。一个算法介绍程序在其思想中使用了广度优先算法。对未遍历过的链接一一发起GET请求,然后响应返回的链接。页面用正则表达式解析,没有发现的新链接被取出,加入集合,在下一个循环中遍历。具体实现使用Map,键值对是链接和是否被遍历的标志。程序中使用的两个地图集
  Java爬虫抓取信息的实现
  
  今天公司有个需求,需要在指定网站查询后做一些数据抓取,所以花了一段时间写了一个demo来演示。思路很简单:就是通过Java访问链接,然后得到html字符串,然后解析链接需要的数据。从技术上讲,Jsoup 是用来方便页面解析的。当然,Jsoup 是非常方便和简单的。一行代码就知道怎么用了: Document doc = Jsoup.connect("") .data("query", "Java") //
  Java爬虫抓取京东HttpCliient+Jsoup上的手机搜索页面
  
  1. 需求及配置需求:抓取京东手机搜索页面的信息,记录每款手机的名称、价格、评论数等,形成数据表,可用于实际分析. 使用Maven项目,log4j记录日志,日志只导出到控制台。Maven依赖以下(pom.xml)org.apache.httpcomponents httpclient
  Python爬虫爬取网页图片地址示例代码
  
  本文的例子主要是抓取网页上的图片地址,如下。读取网页源码: import urllib.request def getHtml(url): html=urllib.request.urlopen(url).read() return html print(getHtml(%E5%A3%81%E7%BA%) B8&amp;ct=201326592&amp;am
  Google 抓取工具如何抓取 JavaScript 内容
  
  我们测试了 Google 爬虫如何抓取 JavaScript,这是我们从中学到的东西。认为 Google 无法处理 JavaScript?再想想。Audette Audette 分享了一系列的测试结果,他和他的同事测试了什么类型的 JavaScript 函数会被 Google 和 收录 抓取。长话短说 1. 我们进行了一系列测试,并确认 Google 可以以多种方式执行和 收录 JavaScript。我们还确认了 Google 可以渲染整个 Page 并读取 DOM,从而可以收录 动态生成内容。2. DOM
  java简单网页爬取的实现方法
  本文介绍了java中简单网页爬虫的实现方法。分享出来供大家参考。具体分析如下: 背景介绍 1 tcp 介绍 1 tcp 在网络中实现点对点传输 2 传输由ports 和sockets 提供不同类型的端口传输(例如http的端口为80) 1)sockets 可以绑定特定的端口,并提供传输功能 2) 一个端口可以连接多个socket 两个 URL 介绍 URL 对 一个简洁的表示获取资源的位置和访问方式from the Internet 是 Internet 上标准资源的地址。Internet 上的每个文件都有一个唯一的
  Python多进程爬取基金网站内容的方法分析
  本文以Python多进程方式抓取基金内容为例网站。分享给大家,供大家参考,如下:在之前的文章///article/162418.htm中,我们已经简单了解了“Python的多进程”,现在需要写爬取的内容Fund 网站(28 页)作为一种多进程方法。因为流程不是越多越好,我们打算分成三个流程。意思是:将要抓取的总共28页分成三部分。如何划分?# 初始范围 r = range(1,29) # 步长 step = 10 myList = [r[x:
  Python爬虫实现爬取京东店铺信息和下载图片功能示例
  本文介绍了Python爬虫实现爬取京东店铺信息和下载图片的功能。分享出来供大家参考,如下: 这是来自bs4 import BeautifulSoup import requests url ='+%C9%D5%CB% AE&amp;type=p&amp;vmarket=&amp;spm=875.7931836%2FA.a2227oh.d100&amp;from=mal
  使用 vbs 从剪贴板中抓取一个 URL,然后在浏览器中打开网站
  问题:您好,ScriptingGuy!如何从剪贴板中获取 URL 并在浏览器中打开网站?--CL 回答:你好,CL。这是一个非常有趣的问题,或者应该说,这是两个非常有趣的问题。因为你实际上问了两个问题。第一个问题很简单:我可以用脚本打开一个特定的网站吗?你可能已经知道答案了,我可以大声回答你,是的!下面是一个示例脚本,它将“脚本中心”的 URL 存储在名为 strURL 的变量中。然后,此脚本创建 WSHShell 对象的实例并使用 Run 查看全部

  java爬虫抓取动态网页(
零基础写Java知乎爬虫之进阶篇抓取一个网站)
  
  搭建开发环境,在项目的Build Path中导入下载的Commons-httpClient3.1.Jar、htmllexer.jar和htmlparser.jar文件。图1. 开发环境搭建HttpClient基础类 该库使用HttpClinet提供了几个支持HTTP访问的类。下面我们通过一些示例代码来熟悉和解释这些类的功能和用途。HttpClient 提供的 HTTP 访问主要通过 GetMethod 类和 PostMethod 类来实现。它们分别对应于HTT
  零基础写Java知乎爬虫进阶篇
  
  说到爬虫,使用Java自带的URLConnection可以实现一些基本的页面爬取功能,但是对于一些更高级的功能,比如重定向处理、去除HTML标签等,单独使用URLConnection是不够的。这里我们可以使用第三方jar包HttpClient。接下来我们用HttpClient写一个简单的爬到百度的demo:import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStr
  从互联网爬取邮箱的Java代码示例
  网络爬虫:其实就是一个用来获取互联网上符合规定规则的数据的程序。包day05; 导入 java.io.BufferedReader; 导入 java.io.IOException; 导入 java.io.InputStreamReader; 导入.URL; 导入java。util.ArrayList; 导入 java.util.List; 导入 java.util.regex.Matcher; 进口
  Java 爬虫实际上抓取了 网站 上的所有链接
  
  前言:在写这篇文章之前,主要看了几个类似的爬虫写法,有的写成队列,感觉不是很直观,有的只有一个请求然后页面分析,没有自动爬行。这也叫爬虫?所以我根据自己的想法写了一个简单的爬虫。一个算法介绍程序在其思想中使用了广度优先算法。对未遍历过的链接一一发起GET请求,然后响应返回的链接。页面用正则表达式解析,没有发现的新链接被取出,加入集合,在下一个循环中遍历。具体实现使用Map,键值对是链接和是否被遍历的标志。程序中使用的两个地图集
  Java爬虫抓取信息的实现
  
  今天公司有个需求,需要在指定网站查询后做一些数据抓取,所以花了一段时间写了一个demo来演示。思路很简单:就是通过Java访问链接,然后得到html字符串,然后解析链接需要的数据。从技术上讲,Jsoup 是用来方便页面解析的。当然,Jsoup 是非常方便和简单的。一行代码就知道怎么用了: Document doc = Jsoup.connect("") .data("query", "Java") //
  Java爬虫抓取京东HttpCliient+Jsoup上的手机搜索页面
  
  1. 需求及配置需求:抓取京东手机搜索页面的信息,记录每款手机的名称、价格、评论数等,形成数据表,可用于实际分析. 使用Maven项目,log4j记录日志,日志只导出到控制台。Maven依赖以下(pom.xml)org.apache.httpcomponents httpclient
  Python爬虫爬取网页图片地址示例代码
  
  本文的例子主要是抓取网页上的图片地址,如下。读取网页源码: import urllib.request def getHtml(url): html=urllib.request.urlopen(url).read() return html print(getHtml(%E5%A3%81%E7%BA%) B8&amp;ct=201326592&amp;am
  Google 抓取工具如何抓取 JavaScript 内容
  
  我们测试了 Google 爬虫如何抓取 JavaScript,这是我们从中学到的东西。认为 Google 无法处理 JavaScript?再想想。Audette Audette 分享了一系列的测试结果,他和他的同事测试了什么类型的 JavaScript 函数会被 Google 和 收录 抓取。长话短说 1. 我们进行了一系列测试,并确认 Google 可以以多种方式执行和 收录 JavaScript。我们还确认了 Google 可以渲染整个 Page 并读取 DOM,从而可以收录 动态生成内容。2. DOM
  java简单网页爬取的实现方法
  本文介绍了java中简单网页爬虫的实现方法。分享出来供大家参考。具体分析如下: 背景介绍 1 tcp 介绍 1 tcp 在网络中实现点对点传输 2 传输由ports 和sockets 提供不同类型的端口传输(例如http的端口为80) 1)sockets 可以绑定特定的端口,并提供传输功能 2) 一个端口可以连接多个socket 两个 URL 介绍 URL 对 一个简洁的表示获取资源的位置和访问方式from the Internet 是 Internet 上标准资源的地址。Internet 上的每个文件都有一个唯一的
  Python多进程爬取基金网站内容的方法分析
  本文以Python多进程方式抓取基金内容为例网站。分享给大家,供大家参考,如下:在之前的文章///article/162418.htm中,我们已经简单了解了“Python的多进程”,现在需要写爬取的内容Fund 网站(28 页)作为一种多进程方法。因为流程不是越多越好,我们打算分成三个流程。意思是:将要抓取的总共28页分成三部分。如何划分?# 初始范围 r = range(1,29) # 步长 step = 10 myList = [r[x:
  Python爬虫实现爬取京东店铺信息和下载图片功能示例
  本文介绍了Python爬虫实现爬取京东店铺信息和下载图片的功能。分享出来供大家参考,如下: 这是来自bs4 import BeautifulSoup import requests url ='+%C9%D5%CB% AE&amp;type=p&amp;vmarket=&amp;spm=875.7931836%2FA.a2227oh.d100&amp;from=mal
  使用 vbs 从剪贴板中抓取一个 URL,然后在浏览器中打开网站
  问题:您好,ScriptingGuy!如何从剪贴板中获取 URL 并在浏览器中打开网站?--CL 回答:你好,CL。这是一个非常有趣的问题,或者应该说,这是两个非常有趣的问题。因为你实际上问了两个问题。第一个问题很简单:我可以用脚本打开一个特定的网站吗?你可能已经知道答案了,我可以大声回答你,是的!下面是一个示例脚本,它将“脚本中心”的 URL 存储在名为 strURL 的变量中。然后,此脚本创建 WSHShell 对象的实例并使用 Run

java爬虫抓取动态网页(伪造网页浏览器证书伪造不到数据数据的解决方案)

网站优化优采云 发表了文章 • 0 个评论 • 49 次浏览 • 2021-12-17 06:16 • 来自相关话题

  java爬虫抓取动态网页(伪造网页浏览器证书伪造不到数据数据的解决方案)
  这个java爬虫程序,在保证可以正常爬取网站的同时,增加了证书伪造,是针对网站反爬取无法抓取数据的解决方案。使用java ArrayList()抓取网站中的有效链接,同时释放资源,以免占用过多系统资源导致系统无法运行和终止。经过测试,确实可以用。
  首先是伪造网页浏览器证书,取得网站的信任,才能顺利抓取数据。具体方案如下:
  public static void getCertificate(){
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
try {
trustAllHttpsCertificates();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
  使用的代码片段太长,已经封装成函数,如下图:
  private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
}
  上述程序中使用的miTM函数如下:
  static class miTM implements javax.net.ssl.TrustManager,javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
}
  好了,到了这里,获取证书的代码就结束了。
  下一步是获取网页静态页面内容的功能:
  public static String returnHtml(String string){
URL url = null;
try {
url= new URL(string);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
URLConnection connection = null;
try {
connection = url.openConnection();
}catch (IOException e1) {
e1.printStackTrace();
}
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
try {
connection.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
InputStreamReader isr = null;
try {
isr=new InputStreamReader(connection.getInputStream(),Charset.forName("UTF-8"));
}catch (IOException e1) {
e1.printStackTrace();
}
// 定义一个字符串用来存储网页内容
String result = "";
// 定义一个缓冲字符输入流
BufferedReader in = null;
// 初始化 BufferedReader输入流来读取URL的响应
in = new BufferedReader(isr);
// 用来临时存储抓取到的每一行的数据
String line;
try {
while ((line = in.readLine()) != null) {
// 遍历抓取到的每一行并将其存储到result里面
result += line;
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
return result;
}
  仅仅获取网页的静态资源是不够的。我们还需要抓取页面上的链接并进行迭代访问以获得我们最终想要的数据:
  public static void getLink(String result){
Document doc = Jsoup.parse(result);
Elements table = doc.select("table.resulttable");
Elements es=table.select("a");
for (Iterator it = es.iterator(); it.hasNext();) {
Element e = (Element) it.next();
link.add(e.attr("href"));
System.out.println(e.text()+" "+e.attr("href"));
}
}
  如果一些网站安全方面比较好,页面的数据会被Ajax动态加载。在这种情况下,我们需要通过ajax后台访问接口获取数据,然后进行链接拼接,然后直接访问后台数据接口获取json数据。具体方案如下:
<p>public static void getJson(ArrayList link){
FileOutputStream out=null;
try{
out = new FileOutputStream(new File("C:\\Users\\yihong\\Desktop\\数据抓取.txt"),true);
}catch(FileNotFoundException e){
}
String s;
for(int i=0;i 查看全部

  java爬虫抓取动态网页(伪造网页浏览器证书伪造不到数据数据的解决方案)
  这个java爬虫程序,在保证可以正常爬取网站的同时,增加了证书伪造,是针对网站反爬取无法抓取数据的解决方案。使用java ArrayList()抓取网站中的有效链接,同时释放资源,以免占用过多系统资源导致系统无法运行和终止。经过测试,确实可以用。
  首先是伪造网页浏览器证书,取得网站的信任,才能顺利抓取数据。具体方案如下:
  public static void getCertificate(){
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
try {
trustAllHttpsCertificates();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
  使用的代码片段太长,已经封装成函数,如下图:
  private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
}
  上述程序中使用的miTM函数如下:
  static class miTM implements javax.net.ssl.TrustManager,javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)throws java.security.cert.CertificateException {
return;
}
}
  好了,到了这里,获取证书的代码就结束了。
  下一步是获取网页静态页面内容的功能:
  public static String returnHtml(String string){
URL url = null;
try {
url= new URL(string);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
URLConnection connection = null;
try {
connection = url.openConnection();
}catch (IOException e1) {
e1.printStackTrace();
}
connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
try {
connection.connect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
InputStreamReader isr = null;
try {
isr=new InputStreamReader(connection.getInputStream(),Charset.forName("UTF-8"));
}catch (IOException e1) {
e1.printStackTrace();
}
// 定义一个字符串用来存储网页内容
String result = "";
// 定义一个缓冲字符输入流
BufferedReader in = null;
// 初始化 BufferedReader输入流来读取URL的响应
in = new BufferedReader(isr);
// 用来临时存储抓取到的每一行的数据
String line;
try {
while ((line = in.readLine()) != null) {
// 遍历抓取到的每一行并将其存储到result里面
result += line;
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
return result;
}
  仅仅获取网页的静态资源是不够的。我们还需要抓取页面上的链接并进行迭代访问以获得我们最终想要的数据:
  public static void getLink(String result){
Document doc = Jsoup.parse(result);
Elements table = doc.select("table.resulttable");
Elements es=table.select("a");
for (Iterator it = es.iterator(); it.hasNext();) {
Element e = (Element) it.next();
link.add(e.attr("href"));
System.out.println(e.text()+" "+e.attr("href"));
}
}
  如果一些网站安全方面比较好,页面的数据会被Ajax动态加载。在这种情况下,我们需要通过ajax后台访问接口获取数据,然后进行链接拼接,然后直接访问后台数据接口获取json数据。具体方案如下:
<p>public static void getJson(ArrayList link){
FileOutputStream out=null;
try{
out = new FileOutputStream(new File("C:\\Users\\yihong\\Desktop\\数据抓取.txt"),true);
}catch(FileNotFoundException e){
}
String s;
for(int i=0;i

java爬虫抓取动态网页(Web网络爬虫系统的原理及应用)

网站优化优采云 发表了文章 • 0 个评论 • 64 次浏览 • 2021-12-17 01:29 • 来自相关话题

  java爬虫抓取动态网页(Web网络爬虫系统的原理及应用)
  1、 爬虫技术概述
  网络爬虫是按照一定的规则自动抓取万维网上信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,可以自动将采集它所能访问的页面的所有内容获取或更新这些网站@的内容和检索方法&gt;. 从功能上来说,爬虫一般分为三部分:数据采集、处理、存储。传统爬虫从一个或多个初始网页的网址开始,获取初始网页上的网址。在爬取网页的过程中,他们不断地从当前页面中提取新的URL并将它们放入队列中,直到满足系统的某个停止条件。聚焦爬虫的工作流程比较复杂。需要按照一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
  (1) 爬取目标的描述或定义;
  (2) 对网页或数据的分析和过滤;
  (3) URL 搜索策略。
  
  2、爬取的原理
  2.1 网络爬虫原理
  网络爬虫系统的作用是下载网页数据,为搜索引擎系统提供数据源。许多大型互联网搜索引擎系统被称为基于Web数据的搜索引擎系统,如谷歌和百度。这说明了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文本信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程就像一个爬虫或蜘蛛在网络上漫游,所以被称为网络爬虫系统或网络蜘蛛系统,英文称为Spider或Crawler。
  
  2.2 网络爬虫系统的工作原理
  在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页并处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等内容。爬虫的基本工作由解析器完成。资源库用于存储下载的网页资源,一般使用Oracle数据库等大型数据库存储,并建立索引。
  控制器
  控制器是网络爬虫的中央控制器。主要负责根据系统传递过来的URL链接分配一个线程,然后启动线程调用爬虫对网页进行爬取。
  解析器
  解析器是负责网络爬虫的主要部分。它的主要任务包括:下载网页,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
  资源库
  主要用于存储网页中下载的数据记录,并提供生成索引的目标源。中大型数据库产品包括:Oracle、Sql Server等。
  网络爬虫系统一般会选择一些输出度(网页中超链接的数量)较高的比较重要的URL作为种子URL集合。网络爬虫系统使用这些种子集作为初始 URL 开始数据爬取。由于网页收录链接信息,因此可以通过现有网页的网址获取一些新的网址。网页之间的指向结构可以看作是一个森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能会导致爬虫系统陷入网站内部,不利于在靠近网站首页的网页上搜索信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。
  
  网络爬虫的基本工作流程如下:
  1.先选择一部分精心挑选的种子网址;
  2.将这些URL放入URL队列中进行抓取;
  3. 从待爬取的URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页并保存到下载的网页库中。另外,将这些网址放入已爬取的网址队列中。
  4.对爬取的URL队列中的URL进行分析,分析其中的其他URL,将这些URL放入待爬取的URL队列中,从而进入下一个循环。
  
  
  2.3 爬取策略
  在爬虫系统中,要爬取的URL队列是一个非常重要的部分。URL队列中要爬取的URL按什么顺序排列也是一个很重要的问题,因为它涉及到先爬哪个页面,后爬哪个页面。确定这些 URL 顺序的方法称为抓取策略。下面重点介绍几种常见的爬取策略:
  2.3.1 深度优先遍历策略
  深度优先遍历策略是指网络爬虫会从起始页开始,逐个跟踪每一个链接,处理完这一行后转移到下一个起始页,继续跟踪链接。我们以下图为例:
  遍历的路径:AFG EHI BCD
  
  2.3.2 广度优先遍历策略
  广度优先遍历策略的基本思想是将新下载的网页中找到的链接直接插入到待爬取的URL队列的末尾。即网络爬虫会先抓取起始网页中所有链接的网页,然后选择其中一个链接的网页,继续抓取该网页中链接的所有网页。以上图为例:
  遍历路径:ABCDEF GHI
  2.3.3 反向链接计数策略
  反向链接数是指从其他网页链接到某个网页的数量。反向链接的数量表示网页内容被他人推荐的程度。因此,很多时候搜索引擎的爬取系统都会使用这个指标来评估网页的重要性,从而决定不同网页的爬取顺序。
  在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量不能完全坐等别人的重视。因此,搜索引擎通常会考虑一些可靠的反向链接。
  2.3.4Partial PageRank 策略
  Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,连同要爬取的URL队列中的URL,组成一个网页集,计算每个页面的PageRank值,经过计算完成后,将要爬取的URL队列中的URL按照PageRank值的大小进行排列,依次爬取页面。
  如果每个页面都被抓取,则重新计算 PageRank 值。一个折衷的方案是:每爬取K个页面后,重新计算PageRank值。但是,这种情况下仍然存在一个问题:对于已经从下载页面中分析出来的链接,也就是我们前面提到的未知网页部分,暂时没有PageRank值。为了解决这个问题,这些页面会被赋予一个临时的PageRank值:将所有传入该页面链中的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排名。以下示例说明:
  2.3.5OPIC 策略
  该算法实际上对页面的重要性进行评分。在算法开始之前,给所有页面相同的初始现金(cash)。下载某个页面P后,将P的现金分配给所有从P解析的链接,清空P的现金。待抓取的 URL 队列中的所有页面均按照现金的数量进行排序。
  2.3.六大站优先策略
  URL队列中所有要爬取的网页,按照所属的网站进行分类。网站需要下载的页面较多,优先下载。这种策略因此被称为大站优先策略。
  3、 爬虫分类
  我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫基本上可以分为三类:
  (1)分布式爬虫:Nutch
  (2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
  (3)非JAVA爬虫:scrapy(基于Python语言开发)
  3.1 个分布式爬虫
  爬虫采用分布式,主要解决两个问题:
  1)海量网址管理
  2)网速
  最流行的分布式爬虫是 Apache 的 Nutch。但是对于大多数用户来说,Nutch 是这些类型的爬虫中最糟糕的选择,原因如下:
  1)Nutch 是一款专为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的一组进程中有三分之二是为搜索引擎设计的。精细提取没有多大意义。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发,让Nutch适合精炼业务,你基本上会破坏Nutch的框架,将Nutch改得面目全非,并有能力修改Nutch。自己写一个新的确实更好。分布式爬虫框架。
  2)Nutch 依赖于hadoop 来运行,而hadoop 本身也消耗了大量的时间。如果集群机器数量少,爬取速度不如单机爬虫快。
  3) 虽然Nutch有一套插件机制,但也被宣传为一个亮点。可以看到一些开源的Nutch插件,提供精细的提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多烂。使用反射机制加载和调用插件使得编写和调试程序变得极其困难,更不用说在其上开发复杂的精细提取系统了。并且Nutch没有提供相应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点是为搜索引擎服务的,不提供精细提取的挂载点。Nutch的大部分精提取插件都挂载在挂载点“解析器”(parser)上,
  4)使用Nutch进行爬虫的二次开发,爬虫的准备和调试所需的时间往往是单机爬虫的十倍以上。学习Nutch源代码的成本非常高,更何况一个团队中的每个人都必须了解Nutch源代码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
  5) 很多人说Nutch2有gora,可以持久化数据到avro文件、hbase、mysql等,其实很多人理解错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。这不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
  6)Nutch2的版本目前不适合开发。Nutch官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果你想和nutch一起使用hbase(大多数人使用nutch2只是为了使用hbase),你只能在0.90版本左右使用hbase,因此你必须将hadoop版本减少到hadoop 0.2或所以。而且,Nutch2的官方教程更具有误导性。Nutch2有两个教程,分别是Nutch1.x和Nutch2.x。Nutch2.x 官网可以支持转到hbase 0.94。但其实这个Nutch2.x指的是Nutch2.3之前和Nutch2.2.1之后的版本。此版本在官方SVN中不断更新。
  所以,如果你不是搜索引擎,尽量不要选择Nutch作为爬虫。有些团队喜欢效仿。他们之所以坚持选择Nutch开发集约化提取的爬虫,其实是因为Nutch的名气(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目被推迟。
  如果你是一个搜索引擎,Nutch1.x 是一个非常好的选择。Nutch1.x 与 solr 或 es 合作组成了一个非常强大的搜索引擎。如果非要使用Nutch2,建议等到Nutch2.3发布。当前的 Nutch2 是一个非常不稳定的版本。
  
  分布式爬虫平台架构图
  3.2 JAVA爬虫
  这里将JAVA爬虫单独划分为一个类别,因为JAVA在网络爬虫的生态系统中是非常完备的。相关资料也是最全的。这里可能有争议,我只是随便说说。
  其实,开源网络爬虫(框架)的开发很简单,难点复杂的问题(比如DOM树解析定位、字符集检测、海量URL去重)都已经被前人解决了,可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历机器上的文件以查找文件中的信息。没有任何困难。之所以选择开源爬虫框架,是为了省事。比如爬虫URL管理、线程池等模块任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
  用于爬虫的功能。用户比较关心的问题往往是:
  1) 爬虫是否支持多线程,爬虫能不能用agent,能不能抓取重复数据,能不能抓取JS生成的信息?
  那些不支持多线程、代理、过滤重复URL的不叫开源爬虫,叫循环执行http请求。
  js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理页面。所以一种策略是利用这些爬虫来遍历网站,当遇到需要解析的页面时,将页面的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
  2)爬虫可以爬取ajax信息吗?
  网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax http请求,自己生成ajax请求的url,获取返回的数据。如果您自己生成 Ajax 请求,那么使用开源爬虫有什么意义呢?其实还是需要用到开源爬虫的线程池和URL管理功能(比如断点爬取)。
  如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来抓取这些请求?
  爬虫通常被设计成广度遍历或深度遍历的模式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历网站。第一轮爬取是爬取种子集(seeds)中的所有URL。简单的说,就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫遍历这些深度为1的种子(默认为广度遍历)。
  3)爬虫如何爬取网站登录?
  这些开源爬虫都支持在爬取时指定cookies,模拟登录主要是基于cookies。至于如何获取cookie,就不是爬虫的事情了。您可以手动获取cookies,也可以模拟http请求登录,也可以使用模拟浏览器自动登录获取cookies。
  4)爬虫如何从网页中提取信息?
  开源爬虫一般都集成了网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,这里就不评价了。
  5)爬虫是如何保存网页信息的?
  一些爬虫带有一个负责持久化的模块。例如,webmagic 有一个叫做管道的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等中,也有一些爬虫不直接为用户提供数据持久化模块。如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于使用pipeline模块好不好,类似于是否使用ORM来操作数据库的问题,看你的业务了。
  6)爬虫被网站屏蔽了,怎么办?
  爬虫已经被网站拦截了,通常可以通过多个代理(随机代理)解决。但是,这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,自己编写代码来随机获取代理(从数组中)。
  7)网页可以调用爬虫吗?
  爬虫的调用是在Web的服务器端调用的,你可以照常使用。这些爬虫都可以使用。
  8)爬行速度怎么样?
  一个单机的开源爬虫的速度基本可以用到机器网速的极限。爬虫速度慢,往往是因为用户线程少,网速慢,或者持久化数据时与数据库交互速度慢。而这些东西往往是由用户的机器和二次开发代码决定的。这些开源爬虫的速度非常好。
  9)显然代码写对了,爬不出来数据。是不是爬虫有问题?别的爬虫能解决吗?
  如果代码写对了,数据爬不出来,其他爬虫也是一样。在这种情况下,要么 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。无法通过更换爬虫来解决抓取数据失败的问题。
  10)哪个爬虫可以判断网站是否爬完了,哪个爬虫可以根据主题爬取?
  爬虫无法判断网站是否已经爬过,只能尽量覆盖。
  至于基于主题的爬取,爬虫只有向下爬取内容才知道主题是什么。所以它通常是从整体上爬下来,然后去过滤内容。如果觉得抓取过于笼统,可以通过限制网址规律等方法缩小范围。
  11) 哪个爬虫有更好的设计模式和结构?
  设计模式纯属无稽之谈。当软件设计模式好的时候,开发软件,然后总结出几种设计模式。设计模式对软件开发没有指导作用。使用设计模式来设计爬虫只会让爬虫的设计更加臃肿。
  在架构上,开源爬虫目前主要是详细数据结构的设计,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,不谈结构。
  所以对于JAVA开源爬虫,我想,找一个好用的就好了。如果业务复杂,使用哪种爬虫就必须经过复杂的二次开发才能满足需求。
  3.3 个非 Java 爬虫
  在非JAVA语言编写的爬虫中,有很多优秀的爬虫。这里提取为一个类别,不是为了爬虫本身的质量,而是为了larbin、scrapy等爬虫对开发成本的影响。
  先说python爬虫,python可以用30行代码完成JAVA 50行代码的任务。Python 代码编写确实很快,但是在调试代码阶段,Python 代码的调试往往比编码阶段节省的时间消耗的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务不复杂,使用scrapy也是相当不错的,可以轻松完成爬取任务。
  
  上图是Scrapy的架构图。绿线是数据流。首先,从初始 URL 开始,Scheduler 将其交给 Downloader 进行下载。下载完成后,会交给Spider进行分析。需要保存的数据会被发送到Item Pipeline。,即对数据进行后处理。此外,可以在数据流通道中安装各种中间件来进行必要的处理。所以在开发爬虫的时候,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
  对于C++爬虫来说,学习成本会比较大。而且你不能只计算一个人的学习成本。如果软件需要团队开发或交接,那将是很多人的学习成本。软件调试并不是那么容易。
  还有一些ruby、php爬虫,这里不多评论。确实有一些非常小的数据采集任务,用ruby或者php非常方便。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能会产生一些你找不到的bug(人少用少)信息)
  4、反爬虫技术
  由于搜索引擎的流行,网络爬虫已经成为一种非常流行的网络技术。除了专门从事搜索的谷歌、雅虎、微软和百度,几乎每个大型门户网站网站都有自己大大小小的搜索引擎。可以叫出的名字有几十个,不知道的名字也有上万个。对于一个内容驱动的网站来说,难免会被网络爬虫光顾。
  网站上一些智能搜索引擎爬虫的爬取频率比较合理,消耗的资源比较少。但是,很多不良的网络爬虫对网页的爬取能力较差,经常会发送几十甚至上百个请求,重复爬取循环。拿,这种爬虫往往对中小网站是毁灭性的打击,尤其是缺乏爬虫编写经验的程序员写的爬虫,破坏力极强,网站的访问压力会非常大。, 会导致网站 访问缓慢甚至无法访问。
  一般来说,网站从三个方面进行反爬虫:用户请求的Headers、用户行为、网站目录和数据加载方式。前两个比较容易遇到,从这些角度来看,大多数网站都是反爬虫。将采用第三类ajax应用网站,增加爬虫难度。
  4.1 个通过 Headers 的反爬虫
  从用户请求的Headers反爬取是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(部分资源网站的防盗就是检测Referer)。如果遇到这种反爬虫机制,可以直接给爬虫添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者修改Referer值为目标网站域名【注:经常容易被Ignore,通过对请求的抓包分析确定referer,将其添加到模拟访问的请求头中该程序]。对于检测header的反爬虫,在爬虫中修改或添加header很容易绕过。
  4.2 基于用户行为的反爬虫
  网站的另一部分是检测用户行为,比如在短时间内从同一个IP多次访问同一个页面,或者在短时间内在同一个账号内多次执行相同的操作. 【这种反爬需要足够的ip来应对】
  大部分网站都是前一种情况。在这种情况下,使用IP代理可以解决。可以专门写一个爬虫来爬取网上公开的代理ip,检测后全部保存。这类代理ip爬虫经常用到,最好自己准备一个。代理IP数量较多后,可以每隔几次请求换一个IP。这在requests或urllib2中很容易做到,这样你就可以轻松绕过第一个反爬虫。【点评:动态拨号也是一种解决方案】
  在第二种情况下,您可以在每次请求后以几秒钟的随机间隔发出下一个请求。一些存在逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求来绕过同一账号不能在短时间内多次发出相同请求的限制。【评论:账号的反爬限制一般很难处理,几秒的随机请求也可能被屏蔽。如果有多个账号,在它们之间切换会有更好的效果】
  4.3 动态页面反爬虫
  以上情况大部分出现在静态页面上,还有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。首先使用Firebug或者HttpFox来分析网络请求【点评:感觉google和IE的网络请求分析也很好】。如果能找到ajax请求,分析出响应的具体参数和具体含义,就可以通过上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
  能够直接模拟ajax请求获取数据是很棒的,但是有的网站加密了ajax请求的所有参数。我们没有办法为我们需要的数据构造一个请求。这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,对接口参数进行加密。遇到这样的网站,就不能用上面的方法了。我使用selenium+phantomJS框架,调用浏览器内核,使用phantomJS执行js模拟人的操作,触发页面中的js脚本。从填表到点击按钮再到滚动页面,一切都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。【评论:支持phantomJS】
  使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面是在一定程度上通过添加Headers来冒充浏览器),它是浏览器本身,phantomJS是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别point-and-touch(12306)或滑动验证码,页面表单的暴力破解等)。它还将在自动化渗透方面大显身手,未来也会如此。提这个。 查看全部

  java爬虫抓取动态网页(Web网络爬虫系统的原理及应用)
  1、 爬虫技术概述
  网络爬虫是按照一定的规则自动抓取万维网上信息的程序或脚本。它们广泛用于互联网搜索引擎或其他类似的网站,可以自动将采集它所能访问的页面的所有内容获取或更新这些网站@的内容和检索方法&gt;. 从功能上来说,爬虫一般分为三部分:数据采集、处理、存储。传统爬虫从一个或多个初始网页的网址开始,获取初始网页上的网址。在爬取网页的过程中,他们不断地从当前页面中提取新的URL并将它们放入队列中,直到满足系统的某个停止条件。聚焦爬虫的工作流程比较复杂。需要按照一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。保留有用的链接并将它们放入 URL 队列中等待被抓取。然后,它会根据一定的搜索策略从队列中选择下一个要抓取的网页的网址,重复上述过程,直到达到系统的某个条件时停止。另外,爬虫爬过的所有网页都会被系统存储起来,进行一定的分析、过滤、索引,以备以后查询检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。爬虫爬过的所有网页都会被系统存储起来进行一定的分析、过滤和索引,以供以后查询和检索;对于专注的爬虫,这个过程中得到的分析结果还是可以对后续的爬虫过程给出反馈和指导的。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个主要问题:
  (1) 爬取目标的描述或定义;
  (2) 对网页或数据的分析和过滤;
  (3) URL 搜索策略。
  
  2、爬取的原理
  2.1 网络爬虫原理
  网络爬虫系统的作用是下载网页数据,为搜索引擎系统提供数据源。许多大型互联网搜索引擎系统被称为基于Web数据的搜索引擎系统,如谷歌和百度。这说明了网络爬虫系统在搜索引擎中的重要性。除了供用户阅读的文本信息外,网页还收录一些超链接信息。网络爬虫系统通过网页中的超链接信息不断获取网络上的其他网页。正是因为这个采集进程就像一个爬虫或蜘蛛在网络上漫游,所以被称为网络爬虫系统或网络蜘蛛系统,英文称为Spider或Crawler。
  
  2.2 网络爬虫系统的工作原理
  在网络爬虫的系统框架中,主要流程由控制器、解析器和资源库三部分组成。控制器的主要工作是为多线程中的每个爬虫线程分配工作任务。解析器的主要工作是下载网页并处理页面,主要是处理一些JS脚本标签、CSS代码内容、空格字符、HTML标签等内容。爬虫的基本工作由解析器完成。资源库用于存储下载的网页资源,一般使用Oracle数据库等大型数据库存储,并建立索引。
  控制器
  控制器是网络爬虫的中央控制器。主要负责根据系统传递过来的URL链接分配一个线程,然后启动线程调用爬虫对网页进行爬取。
  解析器
  解析器是负责网络爬虫的主要部分。它的主要任务包括:下载网页,处理网页的文本,如过滤,提取特殊的HTML标签,分析数据。
  资源库
  主要用于存储网页中下载的数据记录,并提供生成索引的目标源。中大型数据库产品包括:Oracle、Sql Server等。
  网络爬虫系统一般会选择一些输出度(网页中超链接的数量)较高的比较重要的URL作为种子URL集合。网络爬虫系统使用这些种子集作为初始 URL 开始数据爬取。由于网页收录链接信息,因此可以通过现有网页的网址获取一些新的网址。网页之间的指向结构可以看作是一个森林。每个种子 URL 对应的网页是森林中一棵树的根节点。. 这样,网络爬虫系统就可以按照广度优先算法或深度优先算法遍历所有网页。由于深度优先搜索算法可能会导致爬虫系统陷入网站内部,不利于在靠近网站首页的网页上搜索信息,一般采用广度优先搜索算法采集网页。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。网络爬虫系统首先将种子 URL 放入下载队列,然后简单地从队列头部取一个 URL 来下载相应的网页。获取并存储网页内容后,通过解析网页中的链接信息,可以得到一些新的URL,并将这些URL加入到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。并将这些 URL 添加到下载队列中。然后取出一个URL,下载其对应的网页,然后解析,如此周而复始,直到遍历全网或满足某个条件,才会停止。
  
  网络爬虫的基本工作流程如下:
  1.先选择一部分精心挑选的种子网址;
  2.将这些URL放入URL队列中进行抓取;
  3. 从待爬取的URL队列中取出待爬取的URL,解析DNS,获取主机IP,下载该URL对应的网页并保存到下载的网页库中。另外,将这些网址放入已爬取的网址队列中。
  4.对爬取的URL队列中的URL进行分析,分析其中的其他URL,将这些URL放入待爬取的URL队列中,从而进入下一个循环。
  
  
  2.3 爬取策略
  在爬虫系统中,要爬取的URL队列是一个非常重要的部分。URL队列中要爬取的URL按什么顺序排列也是一个很重要的问题,因为它涉及到先爬哪个页面,后爬哪个页面。确定这些 URL 顺序的方法称为抓取策略。下面重点介绍几种常见的爬取策略:
  2.3.1 深度优先遍历策略
  深度优先遍历策略是指网络爬虫会从起始页开始,逐个跟踪每一个链接,处理完这一行后转移到下一个起始页,继续跟踪链接。我们以下图为例:
  遍历的路径:AFG EHI BCD
  
  2.3.2 广度优先遍历策略
  广度优先遍历策略的基本思想是将新下载的网页中找到的链接直接插入到待爬取的URL队列的末尾。即网络爬虫会先抓取起始网页中所有链接的网页,然后选择其中一个链接的网页,继续抓取该网页中链接的所有网页。以上图为例:
  遍历路径:ABCDEF GHI
  2.3.3 反向链接计数策略
  反向链接数是指从其他网页链接到某个网页的数量。反向链接的数量表示网页内容被他人推荐的程度。因此,很多时候搜索引擎的爬取系统都会使用这个指标来评估网页的重要性,从而决定不同网页的爬取顺序。
  在真实的网络环境中,由于广告链接和作弊链接的存在,反向链接的数量不能完全坐等别人的重视。因此,搜索引擎通常会考虑一些可靠的反向链接。
  2.3.4Partial PageRank 策略
  Partial PageRank算法借鉴了PageRank算法的思想:对于下载的网页,连同要爬取的URL队列中的URL,组成一个网页集,计算每个页面的PageRank值,经过计算完成后,将要爬取的URL队列中的URL按照PageRank值的大小进行排列,依次爬取页面。
  如果每个页面都被抓取,则重新计算 PageRank 值。一个折衷的方案是:每爬取K个页面后,重新计算PageRank值。但是,这种情况下仍然存在一个问题:对于已经从下载页面中分析出来的链接,也就是我们前面提到的未知网页部分,暂时没有PageRank值。为了解决这个问题,这些页面会被赋予一个临时的PageRank值:将所有传入该页面链中的PageRank值聚合起来,从而形成未知页面的PageRank值,从而参与排名。以下示例说明:
  2.3.5OPIC 策略
  该算法实际上对页面的重要性进行评分。在算法开始之前,给所有页面相同的初始现金(cash)。下载某个页面P后,将P的现金分配给所有从P解析的链接,清空P的现金。待抓取的 URL 队列中的所有页面均按照现金的数量进行排序。
  2.3.六大站优先策略
  URL队列中所有要爬取的网页,按照所属的网站进行分类。网站需要下载的页面较多,优先下载。这种策略因此被称为大站优先策略。
  3、 爬虫分类
  我应该选择 Nutch、Crawler4j、WebMagic、scrapy、WebCollector 还是其他来开发网络爬虫?上面提到的爬虫基本上可以分为三类:
  (1)分布式爬虫:Nutch
  (2)JAVA 爬虫:Crawler4j、WebMagic、WebCollector
  (3)非JAVA爬虫:scrapy(基于Python语言开发)
  3.1 个分布式爬虫
  爬虫采用分布式,主要解决两个问题:
  1)海量网址管理
  2)网速
  最流行的分布式爬虫是 Apache 的 Nutch。但是对于大多数用户来说,Nutch 是这些类型的爬虫中最糟糕的选择,原因如下:
  1)Nutch 是一款专为搜索引擎设计的爬虫。大多数用户需要一个爬虫来进行准确的数据爬取(精细提取)。Nutch 运行的一组进程中有三分之二是为搜索引擎设计的。精细提取没有多大意义。换句话说,使用 Nutch 进行数据提取会在不必要的计算上浪费大量时间。而如果你试图通过二次开发,让Nutch适合精炼业务,你基本上会破坏Nutch的框架,将Nutch改得面目全非,并有能力修改Nutch。自己写一个新的确实更好。分布式爬虫框架。
  2)Nutch 依赖于hadoop 来运行,而hadoop 本身也消耗了大量的时间。如果集群机器数量少,爬取速度不如单机爬虫快。
  3) 虽然Nutch有一套插件机制,但也被宣传为一个亮点。可以看到一些开源的Nutch插件,提供精细的提取功能。但是任何开发过 Nutch 插件的人都知道 Nutch 的插件系统有多烂。使用反射机制加载和调用插件使得编写和调试程序变得极其困难,更不用说在其上开发复杂的精细提取系统了。并且Nutch没有提供相应的插件挂载点进行精细提取。Nutch的插件只有五六个挂载点,而这五六个挂载点是为搜索引擎服务的,不提供精细提取的挂载点。Nutch的大部分精提取插件都挂载在挂载点“解析器”(parser)上,
  4)使用Nutch进行爬虫的二次开发,爬虫的准备和调试所需的时间往往是单机爬虫的十倍以上。学习Nutch源代码的成本非常高,更何况一个团队中的每个人都必须了解Nutch源代码。在调试过程中,会出现程序本身以外的各种问题(hadoop问题、hbase问题)。
  5) 很多人说Nutch2有gora,可以持久化数据到avro文件、hbase、mysql等,其实很多人理解错了。这里所说的持久化数据是指在avro、hbase、mysql中存储URL信息(URL管理所需的数据)。这不是您要提取的结构化数据。事实上,对于大多数人来说,URL 信息存在于何处并不重要。
  6)Nutch2的版本目前不适合开发。Nutch官方稳定版是nutch2.2.1,但是这个版本绑定了gora-0.3。如果你想和nutch一起使用hbase(大多数人使用nutch2只是为了使用hbase),你只能在0.90版本左右使用hbase,因此你必须将hadoop版本减少到hadoop 0.2或所以。而且,Nutch2的官方教程更具有误导性。Nutch2有两个教程,分别是Nutch1.x和Nutch2.x。Nutch2.x 官网可以支持转到hbase 0.94。但其实这个Nutch2.x指的是Nutch2.3之前和Nutch2.2.1之后的版本。此版本在官方SVN中不断更新。
  所以,如果你不是搜索引擎,尽量不要选择Nutch作为爬虫。有些团队喜欢效仿。他们之所以坚持选择Nutch开发集约化提取的爬虫,其实是因为Nutch的名气(Nutch的作者是Doug Cutting)。当然,最终的结果往往是项目被推迟。
  如果你是一个搜索引擎,Nutch1.x 是一个非常好的选择。Nutch1.x 与 solr 或 es 合作组成了一个非常强大的搜索引擎。如果非要使用Nutch2,建议等到Nutch2.3发布。当前的 Nutch2 是一个非常不稳定的版本。
  
  分布式爬虫平台架构图
  3.2 JAVA爬虫
  这里将JAVA爬虫单独划分为一个类别,因为JAVA在网络爬虫的生态系统中是非常完备的。相关资料也是最全的。这里可能有争议,我只是随便说说。
  其实,开源网络爬虫(框架)的开发很简单,难点复杂的问题(比如DOM树解析定位、字符集检测、海量URL去重)都已经被前人解决了,可以说没有技术含量。包括Nutch,其实Nutch的技术难点就是开发hadoop,代码本身也很简单。从某种意义上说,网络爬虫类似于遍历机器上的文件以查找文件中的信息。没有任何困难。之所以选择开源爬虫框架,是为了省事。比如爬虫URL管理、线程池等模块任何人都可以做,但是需要一段时间的调试和修改才能稳定下来。
  用于爬虫的功能。用户比较关心的问题往往是:
  1) 爬虫是否支持多线程,爬虫能不能用agent,能不能抓取重复数据,能不能抓取JS生成的信息?
  那些不支持多线程、代理、过滤重复URL的不叫开源爬虫,叫循环执行http请求。
  js生成的信息能否被爬取与爬虫本身关系不大。爬虫主要负责遍历网站和下载页面。爬取js产生的信息与网页信息提取模块有关,往往需要通过模拟浏览器(htmlunit、selenium)来完成。这些模拟浏览器通常需要花费大量时间来处理页面。所以一种策略是利用这些爬虫来遍历网站,当遇到需要解析的页面时,将页面的相关信息提交给模拟浏览器,完成对JS生成信息的提取。
  2)爬虫可以爬取ajax信息吗?
  网页上有一些异步加载的数据。爬取这个数据有两种方式:使用模拟浏览器(问题1中描述),或者分析ajax http请求,自己生成ajax请求的url,获取返回的数据。如果您自己生成 Ajax 请求,那么使用开源爬虫有什么意义呢?其实还是需要用到开源爬虫的线程池和URL管理功能(比如断点爬取)。
  如果我已经可以生成我需要的ajax请求(列表),我该如何使用这些爬虫来抓取这些请求?
  爬虫通常被设计成广度遍历或深度遍历的模式来遍历静态或动态页面。爬取ajax信息属于深网(deep web)的范畴,虽然大部分爬虫不直接支持。但它也可以通过某些方式完成。例如,WebCollector 使用广度遍历来遍历网站。第一轮爬取是爬取种子集(seeds)中的所有URL。简单的说,就是将生成的ajax请求作为种子,放入爬虫中。使用爬虫遍历这些深度为1的种子(默认为广度遍历)。
  3)爬虫如何爬取网站登录?
  这些开源爬虫都支持在爬取时指定cookies,模拟登录主要是基于cookies。至于如何获取cookie,就不是爬虫的事情了。您可以手动获取cookies,也可以模拟http请求登录,也可以使用模拟浏览器自动登录获取cookies。
  4)爬虫如何从网页中提取信息?
  开源爬虫一般都集成了网页提取工具。主要支持两种规范:CSS SELECTOR 和 XPATH。至于哪个更好,这里就不评价了。
  5)爬虫是如何保存网页信息的?
  一些爬虫带有一个负责持久化的模块。例如,webmagic 有一个叫做管道的模块。通过简单的配置,爬虫提取的信息可以持久化到文件、数据库等中,也有一些爬虫不直接为用户提供数据持久化模块。如 crawler4j 和 webcollector。让用户在网页处理模块中添加提交数据库的操作。至于使用pipeline模块好不好,类似于是否使用ORM来操作数据库的问题,看你的业务了。
  6)爬虫被网站屏蔽了,怎么办?
  爬虫已经被网站拦截了,通常可以通过多个代理(随机代理)解决。但是,这些开源爬虫一般不直接支持随机代理的切换。因此,用户经常需要将获取到的代理放入一个全局数组中,自己编写代码来随机获取代理(从数组中)。
  7)网页可以调用爬虫吗?
  爬虫的调用是在Web的服务器端调用的,你可以照常使用。这些爬虫都可以使用。
  8)爬行速度怎么样?
  一个单机的开源爬虫的速度基本可以用到机器网速的极限。爬虫速度慢,往往是因为用户线程少,网速慢,或者持久化数据时与数据库交互速度慢。而这些东西往往是由用户的机器和二次开发代码决定的。这些开源爬虫的速度非常好。
  9)显然代码写对了,爬不出来数据。是不是爬虫有问题?别的爬虫能解决吗?
  如果代码写对了,数据爬不出来,其他爬虫也是一样。在这种情况下,要么 网站 阻止了您,要么您抓取的数据是由 javascript 生成的。无法通过更换爬虫来解决抓取数据失败的问题。
  10)哪个爬虫可以判断网站是否爬完了,哪个爬虫可以根据主题爬取?
  爬虫无法判断网站是否已经爬过,只能尽量覆盖。
  至于基于主题的爬取,爬虫只有向下爬取内容才知道主题是什么。所以它通常是从整体上爬下来,然后去过滤内容。如果觉得抓取过于笼统,可以通过限制网址规律等方法缩小范围。
  11) 哪个爬虫有更好的设计模式和结构?
  设计模式纯属无稽之谈。当软件设计模式好的时候,开发软件,然后总结出几种设计模式。设计模式对软件开发没有指导作用。使用设计模式来设计爬虫只会让爬虫的设计更加臃肿。
  在架构上,开源爬虫目前主要是详细数据结构的设计,比如爬取线程池、任务队列等,大家都可以控制。爬虫的业务太简单了,不谈结构。
  所以对于JAVA开源爬虫,我想,找一个好用的就好了。如果业务复杂,使用哪种爬虫就必须经过复杂的二次开发才能满足需求。
  3.3 个非 Java 爬虫
  在非JAVA语言编写的爬虫中,有很多优秀的爬虫。这里提取为一个类别,不是为了爬虫本身的质量,而是为了larbin、scrapy等爬虫对开发成本的影响。
  先说python爬虫,python可以用30行代码完成JAVA 50行代码的任务。Python 代码编写确实很快,但是在调试代码阶段,Python 代码的调试往往比编码阶段节省的时间消耗的时间要多得多。使用python开发,为了保证程序的正确性和稳定性,需要编写更多的测试模块。当然,如果爬取规模不大,爬取业务不复杂,使用scrapy也是相当不错的,可以轻松完成爬取任务。
  
  上图是Scrapy的架构图。绿线是数据流。首先,从初始 URL 开始,Scheduler 将其交给 Downloader 进行下载。下载完成后,会交给Spider进行分析。需要保存的数据会被发送到Item Pipeline。,即对数据进行后处理。此外,可以在数据流通道中安装各种中间件来进行必要的处理。所以在开发爬虫的时候,最好先规划好各个模块。我的做法是分别规划下载模块、爬取模块、调度模块、数据存储模块。
  对于C++爬虫来说,学习成本会比较大。而且你不能只计算一个人的学习成本。如果软件需要团队开发或交接,那将是很多人的学习成本。软件调试并不是那么容易。
  还有一些ruby、php爬虫,这里不多评论。确实有一些非常小的数据采集任务,用ruby或者php非常方便。但是,要选择这些语言的开源爬虫,一方面需要调查相关的生态系统,另一方面,这些开源爬虫可能会产生一些你找不到的bug(人少用少)信息)
  4、反爬虫技术
  由于搜索引擎的流行,网络爬虫已经成为一种非常流行的网络技术。除了专门从事搜索的谷歌、雅虎、微软和百度,几乎每个大型门户网站网站都有自己大大小小的搜索引擎。可以叫出的名字有几十个,不知道的名字也有上万个。对于一个内容驱动的网站来说,难免会被网络爬虫光顾。
  网站上一些智能搜索引擎爬虫的爬取频率比较合理,消耗的资源比较少。但是,很多不良的网络爬虫对网页的爬取能力较差,经常会发送几十甚至上百个请求,重复爬取循环。拿,这种爬虫往往对中小网站是毁灭性的打击,尤其是缺乏爬虫编写经验的程序员写的爬虫,破坏力极强,网站的访问压力会非常大。, 会导致网站 访问缓慢甚至无法访问。
  一般来说,网站从三个方面进行反爬虫:用户请求的Headers、用户行为、网站目录和数据加载方式。前两个比较容易遇到,从这些角度来看,大多数网站都是反爬虫。将采用第三类ajax应用网站,增加爬虫难度。
  4.1 个通过 Headers 的反爬虫
  从用户请求的Headers反爬取是最常见的反爬取策略。很多网站会检测Headers的User-Agent,有的网站会检测Referer(部分资源网站的防盗就是检测Referer)。如果遇到这种反爬虫机制,可以直接给爬虫添加Headers,将浏览器的User-Agent复制到爬虫的Headers中;或者修改Referer值为目标网站域名【注:经常容易被Ignore,通过对请求的抓包分析确定referer,将其添加到模拟访问的请求头中该程序]。对于检测header的反爬虫,在爬虫中修改或添加header很容易绕过。
  4.2 基于用户行为的反爬虫
  网站的另一部分是检测用户行为,比如在短时间内从同一个IP多次访问同一个页面,或者在短时间内在同一个账号内多次执行相同的操作. 【这种反爬需要足够的ip来应对】
  大部分网站都是前一种情况。在这种情况下,使用IP代理可以解决。可以专门写一个爬虫来爬取网上公开的代理ip,检测后全部保存。这类代理ip爬虫经常用到,最好自己准备一个。代理IP数量较多后,可以每隔几次请求换一个IP。这在requests或urllib2中很容易做到,这样你就可以轻松绕过第一个反爬虫。【点评:动态拨号也是一种解决方案】
  在第二种情况下,您可以在每次请求后以几秒钟的随机间隔发出下一个请求。一些存在逻辑漏洞的网站可以通过多次请求、注销、重新登录、继续请求来绕过同一账号不能在短时间内多次发出相同请求的限制。【评论:账号的反爬限制一般很难处理,几秒的随机请求也可能被屏蔽。如果有多个账号,在它们之间切换会有更好的效果】
  4.3 动态页面反爬虫
  以上情况大部分出现在静态页面上,还有一些网站,我们需要爬取的数据是通过ajax请求获取的,或者通过Java生成的。首先使用Firebug或者HttpFox来分析网络请求【点评:感觉google和IE的网络请求分析也很好】。如果能找到ajax请求,分析出响应的具体参数和具体含义,就可以通过上面的方法直接使用requests或者urllib2来模拟ajax请求,分析响应json得到需要的数据。
  能够直接模拟ajax请求获取数据是很棒的,但是有的网站加密了ajax请求的所有参数。我们没有办法为我们需要的数据构造一个请求。这几天爬的网站就是这样的。除了对ajax参数进行加密外,还封装了一些基础功能,都是调用自己的接口,对接口参数进行加密。遇到这样的网站,就不能用上面的方法了。我使用selenium+phantomJS框架,调用浏览器内核,使用phantomJS执行js模拟人的操作,触发页面中的js脚本。从填表到点击按钮再到滚动页面,一切都可以模拟,不管具体的请求和响应过程,只是一个完整的模拟人们浏览页面获取数据的过程。【评论:支持phantomJS】
  使用这个框架几乎可以绕过大部分反爬虫,因为它不是冒充浏览器获取数据(上面是在一定程度上通过添加Headers来冒充浏览器),它是浏览器本身,phantomJS是一个没有界面的浏览器,但控制浏览器的不是人。使用selenium+phantomJS可以做很多事情,比如识别point-and-touch(12306)或滑动验证码,页面表单的暴力破解等)。它还将在自动化渗透方面大显身手,未来也会如此。提这个。

java爬虫抓取动态网页(java爬虫抓取动态网页需要一个java框架(一))

网站优化优采云 发表了文章 • 0 个评论 • 49 次浏览 • 2021-12-14 14:06 • 来自相关话题

  java爬虫抓取动态网页(java爬虫抓取动态网页需要一个java框架(一))
  java爬虫抓取动态网页需要一个java爬虫框架,而想要有很好的收敛性的话,需要知道很多java基础知识点,经过前期一段时间的学习,在这里就要大佬提供下找一下看看新的网页代码中是否隐藏着一些我们需要的东西。1:常用数据结构hashmap//每个元素存放了key值,当存放的数据量较少时,可以使用1的内存即可,以实现小量元素处理。
  hashmap,扩容随机生成。hashtable、concurrenthashmap、concurrentskiplistmap2:常用算法冒泡排序:以桶来分组或以循环节循环遍历,使得子节点上增加最快最大的数。堆排序:多空间排序、尽可能以最快的数据更新最小的数,数据可能会存在扩展性与吞吐量方面的问题,可用结构化思维对待java里这部分定义性分析。
  归并排序:结构化编程中分解成多个小的分区再求和合并。平衡二叉树:在任意一个节点上存放相同数量的元素的,树每次增加一个,每个节点的层数,不能超过当前个数,否则的话发生递归出现空闲记录的概率较大。二叉树高度log2n(n-。
  1),
  1)。
  选择排序:按logn(n-
  1)次方遍历所有节点的方法。动态规划:迭代算法、贪心算法等。3:常用集合枚举,set(集合),fole(列表,queue)java中的集合可以说是按照元素的种类来划分:listlist代表列表;列表中的元素需要通过[位置]来标记,列表元素之间也存在关系,是一种容器,有长度可以是3或者更多;collectionablelist是聚合(incomplete)的存储结构,arry-collection是一个集合,它将arraylist的collection等同于原子操作。
  list的使用arraylist和vector不能使用objectstring来传递这两个java中的列表类型的值;list的生命周期list代表列表,它既可以是一个数组也可以是一个链表。list的方法注意的问题分配空间和迭代方法使用列表引用方法一般就是直接size方法实现在底层,其他方法在初始化阶段都是和arraylist不一样的方法。
<p>size方法提供的是给元素的长度。streamlinearstream是一种模拟一次分组操作过程,因为它可以像数组操作一样直接操作数组元素。inorderfilter是使用了sort()方法的for循环for循环是list类的核心方法之一。for(inti=0;i 查看全部

  java爬虫抓取动态网页(java爬虫抓取动态网页需要一个java框架(一))
  java爬虫抓取动态网页需要一个java爬虫框架,而想要有很好的收敛性的话,需要知道很多java基础知识点,经过前期一段时间的学习,在这里就要大佬提供下找一下看看新的网页代码中是否隐藏着一些我们需要的东西。1:常用数据结构hashmap//每个元素存放了key值,当存放的数据量较少时,可以使用1的内存即可,以实现小量元素处理。
  hashmap,扩容随机生成。hashtable、concurrenthashmap、concurrentskiplistmap2:常用算法冒泡排序:以桶来分组或以循环节循环遍历,使得子节点上增加最快最大的数。堆排序:多空间排序、尽可能以最快的数据更新最小的数,数据可能会存在扩展性与吞吐量方面的问题,可用结构化思维对待java里这部分定义性分析。
  归并排序:结构化编程中分解成多个小的分区再求和合并。平衡二叉树:在任意一个节点上存放相同数量的元素的,树每次增加一个,每个节点的层数,不能超过当前个数,否则的话发生递归出现空闲记录的概率较大。二叉树高度log2n(n-。
  1),
  1)。
  选择排序:按logn(n-
  1)次方遍历所有节点的方法。动态规划:迭代算法、贪心算法等。3:常用集合枚举,set(集合),fole(列表,queue)java中的集合可以说是按照元素的种类来划分:listlist代表列表;列表中的元素需要通过[位置]来标记,列表元素之间也存在关系,是一种容器,有长度可以是3或者更多;collectionablelist是聚合(incomplete)的存储结构,arry-collection是一个集合,它将arraylist的collection等同于原子操作。
  list的使用arraylist和vector不能使用objectstring来传递这两个java中的列表类型的值;list的生命周期list代表列表,它既可以是一个数组也可以是一个链表。list的方法注意的问题分配空间和迭代方法使用列表引用方法一般就是直接size方法实现在底层,其他方法在初始化阶段都是和arraylist不一样的方法。
<p>size方法提供的是给元素的长度。streamlinearstream是一种模拟一次分组操作过程,因为它可以像数组操作一样直接操作数组元素。inorderfilter是使用了sort()方法的for循环for循环是list类的核心方法之一。for(inti=0;i

java爬虫抓取动态网页(PHP解析器和PHP相比较,python适合做爬虫吗?)

网站优化优采云 发表了文章 • 0 个评论 • 35 次浏览 • 2021-12-12 17:16 • 来自相关话题

  java爬虫抓取动态网页(PHP解析器和PHP相比较,python适合做爬虫吗?)
  对比python和PHP,python适合爬取。原因如下
  抓取网页本身的界面
  与java、c#、C++、python等其他静态编程语言相比,抓取网页文档的界面更加简洁;相对于其他动态脚本语言,如 perl、shell、python,urllib2 包提供了更完整的 Web 文档 API 访问。(当然红宝石也是不错的选择)
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这就是我们需要模拟用户代理的行为来构造合适的请求的地方,比如模拟用户登录,模拟会话/cookie存储和设置。python中有优秀的第三方包帮你搞定,比如Requests,mechanize
  爬行后处理
  抓取到的网页通常需要进行处理,如过滤html标签、提取文本等。Python的beautifulsoap提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。
  其实很多语言和工具都可以做到以上功能,但是python可以做到最快最干净。人生苦短,你需要python。
  py对linux来说功能很强大,语言也很简单。
  NO.1 快速开发(唯一能比python开发效率更高的语言是rudy) 语言简洁,没有那么多技巧,所以非常清晰易读。
  NO.2 跨平台(由于python开源,比java更能体现“一次编写,到处运行”
  NO.3 解释(无需直接编译、运行/调试代码)
  NO.4 架构选择太多(主要的GUI架构包括wxPython、tkInter、PyGtk、PyQt。
  PHP脚本主要用于以下三个方面:
  服务器端脚本。这是PHP最传统也是最主要的目标领域。要进行这项工作,需要具备以下三点:PHP解析器(CGI或服务器模块)、web
  服务器和网络浏览器。运行web服务器时需要安装配置PHP,然后可以使用web浏览器访问PHP程序的输出,即浏览服务
  PHP 页面在最后。如果您只是在尝试 PHP 编程,那么所有这些都可以在您的家用计算机上运行。有关更多信息,请参阅安装章节。命令行脚本。
  您可以编写一个 PHP 脚本,并且不需要任何服务器或浏览器来运行它。这样,只需要PHP解析器就可以执行。这种用法是
  是 cron(Unix 或 Linux 环境)或 Task Scheduler(Windows 环境)日常运行脚本的理想选择。这些脚本也可用于处理
  管理简单的文本。有关更多信息,请参阅 PHP 的命令行模式。编写桌面应用程序。对于具有图形界面的桌面应用程序,PHP 可能不会
  最好的语言之一,但是如果用户非常精通PHP并且想在客户端应用程序中使用PHP的一些高级功能,他们可以使用PHP-GTK来编写这个
  这些程序。这样,您也可以编写跨平台的应用程序。PHP-GTK 是 PHP 的一个扩展,通常发布的 PHP 包中不收录它。
  网友的观点扩大了:
  之前用PHP Node.js Python写了一个爬虫脚本,简单说一下。
  首先是PHP。先说优点:网上大量的爬取解析html框架,各种工具都可以直接使用,比较省心。缺点:首先,速度/效率是个问题。有一次下载电影海报的时候,因为crontab定时执行,没有优化,打开的php进程太多,直接导致内存爆了。然后语法也很拖沓。关键词太多,不够简洁。给人一种没有经过精心设计的感觉,写起来很麻烦。
  节点.js。优点是效率,效率还是效率。因为网络是异步的,所以基本上和并发数百个进程一样强大。内存和CPU使用量非常小。如果对捕获的数据没有进行复杂的计算和处理,那么系统就会成为瓶颈。基本上就是写入 MySQL 和其他数据库的带宽和 I/O 速度。当然,优点的反面也是缺点。异步网络意味着您需要回调。这时候,如果业务需求是线性的,比如必须等待上一页被爬取到数据,下一页才能被爬取,甚至更多。层依赖,会有可怕的多层回调!基本上这个时候代码结构和逻辑就会乱了。当然,
  最后,让我们谈谈Python。如果你对效率没有极端的要求,那么推荐Python!首先,Python 的语法非常简洁,同一个句子可以少打很多次。那么,Python非常适合数据处理,比如函数参数的打包和解包,列表分析,矩阵处理,非常方便。
  至此,这篇关于python和php的更适合写爬虫的文章介绍到这里。更多适合爬取内容的php和python相关内容,请在面圈教程中搜索之前的文章或者继续浏览下面的相关文章,希望大家多多支持面圈教程将来! 查看全部

  java爬虫抓取动态网页(PHP解析器和PHP相比较,python适合做爬虫吗?)
  对比python和PHP,python适合爬取。原因如下
  抓取网页本身的界面
  与java、c#、C++、python等其他静态编程语言相比,抓取网页文档的界面更加简洁;相对于其他动态脚本语言,如 perl、shell、python,urllib2 包提供了更完整的 Web 文档 API 访问。(当然红宝石也是不错的选择)
  另外,爬取网页有时需要模拟浏览器的行为,很多网站都是为了生硬爬取而被屏蔽的。这就是我们需要模拟用户代理的行为来构造合适的请求的地方,比如模拟用户登录,模拟会话/cookie存储和设置。python中有优秀的第三方包帮你搞定,比如Requests,mechanize
  爬行后处理
  抓取到的网页通常需要进行处理,如过滤html标签、提取文本等。Python的beautifulsoap提供了简洁的文档处理功能,可以用极短的代码完成大部分文档处理。
  其实很多语言和工具都可以做到以上功能,但是python可以做到最快最干净。人生苦短,你需要python。
  py对linux来说功能很强大,语言也很简单。
  NO.1 快速开发(唯一能比python开发效率更高的语言是rudy) 语言简洁,没有那么多技巧,所以非常清晰易读。
  NO.2 跨平台(由于python开源,比java更能体现“一次编写,到处运行”
  NO.3 解释(无需直接编译、运行/调试代码)
  NO.4 架构选择太多(主要的GUI架构包括wxPython、tkInter、PyGtk、PyQt。
  PHP脚本主要用于以下三个方面:
  服务器端脚本。这是PHP最传统也是最主要的目标领域。要进行这项工作,需要具备以下三点:PHP解析器(CGI或服务器模块)、web
  服务器和网络浏览器。运行web服务器时需要安装配置PHP,然后可以使用web浏览器访问PHP程序的输出,即浏览服务
  PHP 页面在最后。如果您只是在尝试 PHP 编程,那么所有这些都可以在您的家用计算机上运行。有关更多信息,请参阅安装章节。命令行脚本。
  您可以编写一个 PHP 脚本,并且不需要任何服务器或浏览器来运行它。这样,只需要PHP解析器就可以执行。这种用法是
  是 cron(Unix 或 Linux 环境)或 Task Scheduler(Windows 环境)日常运行脚本的理想选择。这些脚本也可用于处理
  管理简单的文本。有关更多信息,请参阅 PHP 的命令行模式。编写桌面应用程序。对于具有图形界面的桌面应用程序,PHP 可能不会
  最好的语言之一,但是如果用户非常精通PHP并且想在客户端应用程序中使用PHP的一些高级功能,他们可以使用PHP-GTK来编写这个
  这些程序。这样,您也可以编写跨平台的应用程序。PHP-GTK 是 PHP 的一个扩展,通常发布的 PHP 包中不收录它。
  网友的观点扩大了:
  之前用PHP Node.js Python写了一个爬虫脚本,简单说一下。
  首先是PHP。先说优点:网上大量的爬取解析html框架,各种工具都可以直接使用,比较省心。缺点:首先,速度/效率是个问题。有一次下载电影海报的时候,因为crontab定时执行,没有优化,打开的php进程太多,直接导致内存爆了。然后语法也很拖沓。关键词太多,不够简洁。给人一种没有经过精心设计的感觉,写起来很麻烦。
  节点.js。优点是效率,效率还是效率。因为网络是异步的,所以基本上和并发数百个进程一样强大。内存和CPU使用量非常小。如果对捕获的数据没有进行复杂的计算和处理,那么系统就会成为瓶颈。基本上就是写入 MySQL 和其他数据库的带宽和 I/O 速度。当然,优点的反面也是缺点。异步网络意味着您需要回调。这时候,如果业务需求是线性的,比如必须等待上一页被爬取到数据,下一页才能被爬取,甚至更多。层依赖,会有可怕的多层回调!基本上这个时候代码结构和逻辑就会乱了。当然,
  最后,让我们谈谈Python。如果你对效率没有极端的要求,那么推荐Python!首先,Python 的语法非常简洁,同一个句子可以少打很多次。那么,Python非常适合数据处理,比如函数参数的打包和解包,列表分析,矩阵处理,非常方便。
  至此,这篇关于python和php的更适合写爬虫的文章介绍到这里。更多适合爬取内容的php和python相关内容,请在面圈教程中搜索之前的文章或者继续浏览下面的相关文章,希望大家多多支持面圈教程将来!

java爬虫抓取动态网页(所说的问题试试)

网站优化优采云 发表了文章 • 0 个评论 • 43 次浏览 • 2021-12-11 02:25 • 来自相关话题

  java爬虫抓取动态网页(所说的问题试试)
  是的,最后还是用Selenium来实现上一篇我提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果还是可以接受的。
  继续昨天的话题,既然要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的第一选择是 htmlunit。先简单介绍一下htmlunit。以下段落摘自互联网。
  htmlunit 是一个开源的java 页面分析工具。启动 htmlunit 后,将在底部启动一个无界面浏览器。用户可以指定浏览器类型:firefox、ie等,如果不指定,默认使用INTERNET_EXPLORER_7:
  WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
  通过一个简单的调用:
  HtmlPage 页面 = webClient.getPage(url);
  可以得到页面的HtmlPage表示,然后通过:
  InputStream 是 = targetPage.getWebResponse().getContentAsStream()
  可以获取页面的输入流,进而获取页面的源代码,这对于网络爬虫项目非常有用。
  当然,你也可以从页面中获取更多的页面元素。
  很重要的一点是 HtmlUnit 提供了对执行 javascript 的支持:
  page.executeJavaScript(javascript)
  js执行后返回一个ScriptResult对象,通过该对象可以获取js执行后的页面等信息。默认情况下,内部浏览器执行js后,会做一次页面跳转,跳转到执行js后生成的新页面。如果js执行失败,页面跳转将不会被执行。
  最后可以通过获取 page.executeJavaScript(javascript).getNewPage() 来获取执行后的页面。换句话说,这里需要人工执行JavaScript。显然这不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻页面的时候总是出错。我还没有找到错误在哪里。分析网上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数的顺序或编码问题,请求失败并报错。关键是我运行后没有得到我需要的结果。
  然后我寻找了另一种解决方案。这时候我找到了SeleniumWebDriver,这就是我需要的解决方案。
  参考资料和例子后,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064");
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn");
11 list.add("http://www.sohu.com");
12 list.add("http://www.163.com");
13 list.add("http://www.qq.com");
14
15 long start,end;
16
17 for(int i=0;i 查看全部

  java爬虫抓取动态网页(所说的问题试试)
  是的,最后还是用Selenium来实现上一篇我提到的问题。我没有尝试其他任何东西。我只试过火狐引擎。整体效果还是可以接受的。
  继续昨天的话题,既然要实现上一篇提到的问题,就需要一个可以执行js代码的框架。我的第一选择是 htmlunit。先简单介绍一下htmlunit。以下段落摘自互联网。
  htmlunit 是一个开源的java 页面分析工具。启动 htmlunit 后,将在底部启动一个无界面浏览器。用户可以指定浏览器类型:firefox、ie等,如果不指定,默认使用INTERNET_EXPLORER_7:
  WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
  通过一个简单的调用:
  HtmlPage 页面 = webClient.getPage(url);
  可以得到页面的HtmlPage表示,然后通过:
  InputStream 是 = targetPage.getWebResponse().getContentAsStream()
  可以获取页面的输入流,进而获取页面的源代码,这对于网络爬虫项目非常有用。
  当然,你也可以从页面中获取更多的页面元素。
  很重要的一点是 HtmlUnit 提供了对执行 javascript 的支持:
  page.executeJavaScript(javascript)
  js执行后返回一个ScriptResult对象,通过该对象可以获取js执行后的页面等信息。默认情况下,内部浏览器执行js后,会做一次页面跳转,跳转到执行js后生成的新页面。如果js执行失败,页面跳转将不会被执行。
  最后可以通过获取 page.executeJavaScript(javascript).getNewPage() 来获取执行后的页面。换句话说,这里需要人工执行JavaScript。显然这不符合我的初衷。另外,我的水平可能太差了。我在爬新浪新闻页面的时候总是出错。我还没有找到错误在哪里。分析网上的查询结果,最可能的错误原因是htmlunit在执行一些带参数的请求时,由于参数的顺序或编码问题,请求失败并报错。关键是我运行后没有得到我需要的结果。
  然后我寻找了另一种解决方案。这时候我找到了SeleniumWebDriver,这就是我需要的解决方案。
  参考资料和例子后,就可以开始使用了。示例代码如下。
<p> 1 File pathToBinary = new File("D:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
2 FirefoxBinary ffBinary = new FirefoxBinary(pathToBinary);
3 FirefoxProfile firefoxProfile = new FirefoxProfile();
4 FirefoxDriver driver = new FirefoxDriver(ffBinary,firefoxProfile);
5
6
7 driver.get("http://cq.qq.com/baoliao/detail.htm?294064";);
8
9 ArrayList list = new ArrayList();
10 list.add("http://www.sina.com.cn";);
11 list.add("http://www.sohu.com";);
12 list.add("http://www.163.com";);
13 list.add("http://www.qq.com";);
14
15 long start,end;
16
17 for(int i=0;i

java爬虫抓取动态网页(为什么大多数人喜欢用Python呢?答案是这样的!)

网站优化优采云 发表了文章 • 0 个评论 • 68 次浏览 • 2021-12-10 19:06 • 来自相关话题

  java爬虫抓取动态网页(为什么大多数人喜欢用Python呢?答案是这样的!)
  内容
  爬虫一定要使用Python吗?
  你可以使用Java,或者C。编程语言只是工具。抓取数据是目的。
  您可以使用任何工具来实现您的目标。就像吃饭一样,你可以用叉子或筷子。最终的结果是你可以吃。那么为什么大多数人喜欢使用Python呢?答:因为 Python 编写爬虫很容易。不明白?问:为什么吃米饭不用刀叉?用筷子吗?因为这很容易!使用方便!
  在众多编程语言中,Python 上手最快,语法最简单。更重要的是,有很多第三方支持库可供爬虫使用。
  爬行动物的矛和盾
  防爬机构
  门户 网站。可以制定相应的策略或技术手段,防止爬虫爬取网站数据。
  防反爬策略
  爬虫程序可以通过制定相关策略或技术手段破解门户网站中的反爬虫机制,从而获取门户网站中的相关数据。
  软件:
  jupyter 笔记本
  蟒蛇3.8
  pycharm
  安装python注意配置环境变量:
  Python环境变量的配置-知乎()
  
  你可以参考上面的
  在cmd上输入python
  
  如果你弹出商店页面:
  
  只需将python路径调整到路径上的第一个位置即可。
  入门案例:
  显示百度页面:
  from urllib.request import urlopen
url = "http://www.baidu.com"
resp = urlopen(url)
# print(resp.read().decode("utf-8"))#转换为解码
with open("mybaidu.html", mode="w") as f:
f.write(resp.read().decode("utf-8"))
print("over!")
  生成的文件可以在浏览器中打开,就是百度的页面。 查看全部

  java爬虫抓取动态网页(为什么大多数人喜欢用Python呢?答案是这样的!)
  内容
  爬虫一定要使用Python吗?
  你可以使用Java,或者C。编程语言只是工具。抓取数据是目的。
  您可以使用任何工具来实现您的目标。就像吃饭一样,你可以用叉子或筷子。最终的结果是你可以吃。那么为什么大多数人喜欢使用Python呢?答:因为 Python 编写爬虫很容易。不明白?问:为什么吃米饭不用刀叉?用筷子吗?因为这很容易!使用方便!
  在众多编程语言中,Python 上手最快,语法最简单。更重要的是,有很多第三方支持库可供爬虫使用。
  爬行动物的矛和盾
  防爬机构
  门户 网站。可以制定相应的策略或技术手段,防止爬虫爬取网站数据。
  防反爬策略
  爬虫程序可以通过制定相关策略或技术手段破解门户网站中的反爬虫机制,从而获取门户网站中的相关数据。
  软件:
  jupyter 笔记本
  蟒蛇3.8
  pycharm
  安装python注意配置环境变量:
  Python环境变量的配置-知乎()
  
  你可以参考上面的
  在cmd上输入python
  
  如果你弹出商店页面:
  
  只需将python路径调整到路径上的第一个位置即可。
  入门案例:
  显示百度页面:
  from urllib.request import urlopen
url = "http://www.baidu.com"
resp = urlopen(url)
# print(resp.read().decode("utf-8"))#转换为解码
with open("mybaidu.html", mode="w") as f:
f.write(resp.read().decode("utf-8"))
print("over!")
  生成的文件可以在浏览器中打开,就是百度的页面。

java爬虫抓取动态网页( wpfgaoerfu:wpfgaoerfu如何从动态加载网页抓取数据(图))

网站优化优采云 发表了文章 • 0 个评论 • 30 次浏览 • 2021-12-10 14:16 • 来自相关话题

  java爬虫抓取动态网页(
wpfgaoerfu:wpfgaoerfu如何从动态加载网页抓取数据(图))
  python爬虫从动态加载的网页中抓取数据
  2020年4月13日第14读 来源:wpfgaoerfu
  如何从动态加载的网页中抓取数据1、获取请求的网页打开网址:如#/?tab=%E5%85%A8%E9%83%A8 那么如何从该网页加载数据, 点击F12查看
  
  
  2、请求数据,我们看到请求数据是根据page_size获取的,这样我们就可以模拟Request请求,获取数据请看下面的代码
  import requests
# 1.分析网站真是请求地址---抓包分析
def get_json(url):
# 伪装 程序伪装成浏览器
headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'}
params = {
'page_size' : 10,
'next_offset': str(num), # 不断变化
'tag': '今日热门',
'platform': 'pc'
}
# url = 'https://api.vc.bilibili.com/board/v1/ranking/top?' # 找到真实请求地址
html = requests.get(url,params=params, headers=headers)
# print(html)
return html.json()
# 抓取大量数据 大量地址
# 1 11 21 31 41 :递增10 一个真实请求地址:包含10个视频
if __name__ == '__main__': # 可写可不写
for i in range(10):
url = 'https://api.vc.bilibili.com/board/v1/ranking/top?'
num = i * 10 + 1 # num == offset
html = get_json(url)
# 2.解析数据
infos = html['data']['items']
# print(infos)#list 列表[] ()tuple元祖 {}dict字典
for info in infos:
title = info['item']['description']
vedio_url = info['item']['video_playurl']
print(title, vedio_url)
  运行结果如下:
  获取每个视频地址,点击打开下载或观看
  
  以上就是从动态网页中抓取数据的整个过程的简单实现
  欢迎交流学习。 查看全部

  java爬虫抓取动态网页(
wpfgaoerfu:wpfgaoerfu如何从动态加载网页抓取数据(图))
  python爬虫从动态加载的网页中抓取数据
  2020年4月13日第14读 来源:wpfgaoerfu
  如何从动态加载的网页中抓取数据1、获取请求的网页打开网址:如#/?tab=%E5%85%A8%E9%83%A8 那么如何从该网页加载数据, 点击F12查看
  
  
  2、请求数据,我们看到请求数据是根据page_size获取的,这样我们就可以模拟Request请求,获取数据请看下面的代码
  import requests
# 1.分析网站真是请求地址---抓包分析
def get_json(url):
# 伪装 程序伪装成浏览器
headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'}
params = {
'page_size' : 10,
'next_offset': str(num), # 不断变化
'tag': '今日热门',
'platform': 'pc'
}
# url = 'https://api.vc.bilibili.com/board/v1/ranking/top?' # 找到真实请求地址
html = requests.get(url,params=params, headers=headers)
# print(html)
return html.json()
# 抓取大量数据 大量地址
# 1 11 21 31 41 :递增10 一个真实请求地址:包含10个视频
if __name__ == '__main__': # 可写可不写
for i in range(10):
url = 'https://api.vc.bilibili.com/board/v1/ranking/top?'
num = i * 10 + 1 # num == offset
html = get_json(url)
# 2.解析数据
infos = html['data']['items']
# print(infos)#list 列表[] ()tuple元祖 {}dict字典
for info in infos:
title = info['item']['description']
vedio_url = info['item']['video_playurl']
print(title, vedio_url)
  运行结果如下:
  获取每个视频地址,点击打开下载或观看
  
  以上就是从动态网页中抓取数据的整个过程的简单实现
  欢迎交流学习。

java爬虫抓取动态网页(java网络爬虫基础入门的总结及解决方法)

网站优化优采云 发表了文章 • 0 个评论 • 39 次浏览 • 2021-12-08 19:18 • 来自相关话题

  java爬虫抓取动态网页(java网络爬虫基础入门的总结及解决方法)
  刚开始接触java爬虫,这里总结一下网上搜索的一些理论知识
  主要参考文章:Gitchat的java网络爬虫基础,好像是收费的,不贵,感觉内容对新手很友好。
  一、爬虫介绍
  网络爬虫是一种自动提取网页的程序。它从万维网上下载网页供搜索引擎使用,是搜索引擎的重要组成部分。
  传统爬虫:
  获取URL-》放入队列-》抓取网页,分析信息-》新增网址-》放入队列-》抓取网页,分析信息...-》满足一定条件时停止。
  专注于爬虫:
  根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后根据搜索策略从队列中选择下一个URL,重复...直到满足一定条件停止。另外,爬虫爬取的网页会被系统存储起来进行一定的分析、过滤、索引,以便后续的查询和还原。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个问题:
  爬网目标的描述或定义。网页或数据的分析和过滤。URL 的搜索策略。
  网络爬虫设计有很多领域。我们需要掌握基本的编程语言(最好是已经有成熟API的语言),了解HTTP协议,了解web服务器、数据库、前端知识、网络安全等……
  分类:
  根据系统结构和实现技术,大致可以分为以下几类:通用网络爬虫、聚焦网络爬虫、增量网络爬虫、深度网络爬虫等。
  通用网络爬虫:爬取对象从一些种子网址扩展到整个Web,主要是门户搜索引擎和大型Web服务商采集数据。
  专注于网络爬虫:也称为主网络爬虫,是指有选择地抓取与​​预定义主题相关的页面,比上述一般的爬虫更具体。
  Incremental web crawler:一种对下载的网页进行增量更新并且只抓取新生成或更改的页面的爬虫。它可以确保抓取的页面尽可能新。历史已经采集上一页不再重复采集。
  常见情况:论坛订单评论数据采集(评论数据仅是用户最近几天或几个月的采集评论)
  深网爬虫:是指大部分内容无法通过静态链接获取,而我们需要的大部分数据是网页动态链接生成的页面,即Deep Web信息。Deep Web 也是一个爬虫框架,这里暂时不赘述。
  网络爬虫的爬取策略
  深度优先搜索策略,广度优先搜索策略。 查看全部

  java爬虫抓取动态网页(java网络爬虫基础入门的总结及解决方法)
  刚开始接触java爬虫,这里总结一下网上搜索的一些理论知识
  主要参考文章:Gitchat的java网络爬虫基础,好像是收费的,不贵,感觉内容对新手很友好。
  一、爬虫介绍
  网络爬虫是一种自动提取网页的程序。它从万维网上下载网页供搜索引擎使用,是搜索引擎的重要组成部分。
  传统爬虫:
  获取URL-》放入队列-》抓取网页,分析信息-》新增网址-》放入队列-》抓取网页,分析信息...-》满足一定条件时停止。
  专注于爬虫:
  根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接,放入URL队列等待被抓取。然后根据搜索策略从队列中选择下一个URL,重复...直到满足一定条件停止。另外,爬虫爬取的网页会被系统存储起来进行一定的分析、过滤、索引,以便后续的查询和还原。
  与一般的网络爬虫相比,聚焦爬虫还需要解决三个问题:
  爬网目标的描述或定义。网页或数据的分析和过滤。URL 的搜索策略。
  网络爬虫设计有很多领域。我们需要掌握基本的编程语言(最好是已经有成熟API的语言),了解HTTP协议,了解web服务器、数据库、前端知识、网络安全等……
  分类:
  根据系统结构和实现技术,大致可以分为以下几类:通用网络爬虫、聚焦网络爬虫、增量网络爬虫、深度网络爬虫等。
  通用网络爬虫:爬取对象从一些种子网址扩展到整个Web,主要是门户搜索引擎和大型Web服务商采集数据。
  专注于网络爬虫:也称为主网络爬虫,是指有选择地抓取与​​预定义主题相关的页面,比上述一般的爬虫更具体。
  Incremental web crawler:一种对下载的网页进行增量更新并且只抓取新生成或更改的页面的爬虫。它可以确保抓取的页面尽可能新。历史已经采集上一页不再重复采集。
  常见情况:论坛订单评论数据采集(评论数据仅是用户最近几天或几个月的采集评论)
  深网爬虫:是指大部分内容无法通过静态链接获取,而我们需要的大部分数据是网页动态链接生成的页面,即Deep Web信息。Deep Web 也是一个爬虫框架,这里暂时不赘述。
  网络爬虫的爬取策略
  深度优先搜索策略,广度优先搜索策略。

java爬虫抓取动态网页(爬虫+基于接口的网络爬虫(爬虫爬虫)(组图))

网站优化优采云 发表了文章 • 0 个评论 • 46 次浏览 • 2021-12-08 19:12 • 来自相关话题

  java爬虫抓取动态网页(爬虫+基于接口的网络爬虫(爬虫爬虫)(组图))
  爬虫+基于接口的网络爬虫
  上一篇讲了【java爬虫】---爬虫+jsoup轻松爬取博客。这种方法有一个很大的局限性,就是只能通过jsoup爬虫爬取静态网页,所以只能爬取当前页面上的所有新闻。如果需要爬取一个网站的所有信息,就需要通过接口反复调整网站的接口,通过改变参数来爬取网站@的所有数据信息&gt;.
  本博客旨在抓取黄金财经新闻资讯,抓取网站自建站以来发布的所有新闻资讯。下面将分步说明。这里重点讲一下思路,最后提供完整的源码。
  第一步:找到界面
  如果要获取这个网站的所有新闻数据,第一步当然是获取接口,通过接口获取所有信息。
  F12--&gt;网络--&gt;全部,找到界面:
  这三个参数的说明:
  limit=23 表示每次调用接口返回23条数据。
  information_id=56630 表示下面返回的23条数据是通过大于56630或小于56630的ID指纹返回的。
  flag=down 表示向下翻页。这里指的是23条ID小于56630的数据。
  通过邮递员测试
  输入:(这里返回两条,这里id=0代表最新的两条数据)
  返回json数据格式:
  
  接口返回信息
  第二步:通过定时任务启动爬虫工作
  @Slf4j
@Component
public class SchedulePressTrigger {
@Autowired
private CrawlerJinSeLivePressService crawlerJinSeLivePressService;
/**
* 定时抓取金色财经的新闻
*/
@Scheduled(initialDelay = 1000, fixedRate = 600 * 1000)
public void doCrawlJinSeLivePress() {
// log.info("开始抓取金色财经新闻, time:" + new Date());
try {
crawlerJinSeLivePressService.start();
} catch (Exception e) {
// log.error("本次抓取金色财经新闻异常", e);
}
// log.info("结束抓取金色财经新闻, time:" + new Date());
}
}
  第三步:主要实现类
  /**
* 抓取金色财经快讯
* @author xub
* @since 2018/6/29
*/
@Slf4j
@Service
public class CrawlerJinSeLivePressServiceImpl extends AbstractCrawlLivePressService implements
CrawlerJinSeLivePressService {
//这个参数代表每一次请求获得多少个数据
private static final int PAGE_SIZE = 15;
//这个是真正翻页参数,每一次找id比它小的15个数据(有写接口是通过page=1,2来进行翻页所以比较好理解一点,其实它们性质一样)
private long bottomId;
//这个这里没有用到,但是如果有数据层,就需要用到,这里我只是把它答应到控制台
@Autowired
private LivePressService livePressService;



//定时任务运行这个方法,doTask没有被重写,所有运行父类的方法
@Override
public void start() {
try {
doTask(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT);
} catch (IOException e) {
// log.error("抓取金色财经新闻异常", e);
}
}
@Override
protected List crawlPage(int pageNum) throws IOException {
// 最多抓取100页,多抓取也没有特别大的意思。
if (pageNum >= 100) {
return Collections.emptyList();
}
// 格式化翻页参数(第一次bottomId为0,第二次就是这次爬到的最小bottomId值)
String requestUrl = String.format(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT, PAGE_SIZE, bottomId);
Response response = OkHttp.singleton().newCall(
new Request.Builder().url(requestUrl).addHeader("referer", CoinPressConsts.CHAIN_FOR_LIVE_URL).get().build())
.execute();
if (response.isRedirect()) {
// 如果请求发生了跳转,说明请求不是原来的地址了,返回空数据。
return Collections.emptyList();
}
//先获得json数据格式
String responseText = response.body().string();
//在通过工具类进行数据赋值
JinSePressResult jinSepressResult = JsonUtils.objectFromJson(responseText, JinSePressResult.class);
if (null == jinSepressResult) {
// 反序列化失败
System.out.println("抓取金色财经新闻列表反序列化异常");
return Collections.emptyList();
}
// 取金色财经最小的记录id,来进行翻页
bottomId = jinSepressResult.getBottomId();
//这个是谷歌提供了guava包里的工具类,Lists这个集合工具,对list集合操作做了些优化提升。
List pageListPresss = Lists.newArrayListWithExpectedSize(PAGE_SIZE);
for (JinSePressResult.DayData dayData : jinSepressResult.getList()) {
JinSePressData data = dayData.getExtra();
//新闻发布时间(时间戳格式)这里可以来判断只爬多久时间以内的新闻
long createTime = data.getPublishedAt() * 1000;
Long timemill=System.currentTimeMillis();
// if (System.currentTimeMillis() - createTime > CoinPressConsts.MAX_CRAWLER_TIME) {
// // 快讯过老了,放弃
// continue;
// }
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sd = sdf.format(new Date(createTime)); // 时间戳转换成时间
Date newsCreateTime=new Date();
try {
//获得新闻发布时间
newsCreateTime = sdf.parse(sd);
} catch (ParseException e) {
e.printStackTrace();
}
//具体文章页面路径(这里可以通过这个路径+jsoup就可以爬新闻正文所有信息了)
String href = data.getTopicUrl();
//新闻摘要
String summary = data.getSummary();
//新闻阅读数量
String pressreadcount = data.getReadNumber();
//新闻标题
String title = dayData.getTitle();
pageListPresss.add(new PageListPress(href,title, Integer.parseInt(pressreadcount),
newsCreateTime , summary));
}
return pageListPresss;
}
}
  AbstractCrawlLivePressService 类
   public abstract class AbstractCrawlLivePressService {
String url;
public void doTask(String url) throws IOException {
this.url = url;
int pageNum = 1;
//通过 while (true)会一直循环调取接口,直到数据为空或者时间过老跳出循环
while (true) {
List newsList = crawlPage(pageNum++);
// 抓取不到新的内容本次抓取结束
if (CollectionUtils.isEmpty(newsList)) {
break;
}
//这里并没有把数据放到数据库,而是直接从控制台输出
for (int i = newsList.size() - 1; i >= 0; i--) {
PageListPress pageListNews = newsList.get(i);
System.out.println(pageListNews.toString());

}
}
}
//这个由具体实现类实现
protected abstract List crawlPage(int pageNum) throws IOException;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class PageListPress {
//新闻详情页面url
private String href;
//新闻标题
private String title;
//新闻阅读数量
private int readCounts;
//新闻发布时间
private Date createTime;
//新闻摘要
private String summary;

}
}
  锦色印刷结果
  /**
*在创建对象的时候一定要分析好json格式的类型
*金色新闻的返回格式就是第一层有普通属性和一个list集合
*在list集合中又有普通属性和一个extra的对象。
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class JinSePressResult {
private int news;
private int count;
@JsonProperty("top_id")
private long topId;
@JsonProperty("bottom_id")
private long bottomId;
//list的名字也要和json数据的list名字一致,否则无用
private List list;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class DayData {
private String title;
//这里对象的属性名extra也要和json的extra名字一致
private JinSePressData extra;
@JsonProperty("topic_url")
private String topicUrl;
}
}
  这里有两点需要注意
  (1) 创建对象时,首先要弄清楚json格式类型是否收录对象中的集合,或者集合中是否有对象等。
  (2) 只能定义自己需要的属性字段。当无法匹配json的属性名但类型不一致时,比如上面改成Listextra,序列化就会失败,因为json的extra明明是一个Object,这里接受的确实是一个集合。关键是要属于
  性别名称相同,所以赋值时会报错,序列化失败。
  第四步:查看操作结果
  这只是截取了控制台输出的部分信息。这样就可以得到网站的所有新闻信息。同时我们已经获取到了具体新闻的URL,那么我们就可以通过JSOup获取到该新闻的所有具体信息了。(完美的)
  
  第五步:数据库去重思路
  因为你不可能每次爬取都直接把播放数据放到数据库中,所以必须比较新闻数据库是否已经存在,如果不存在就放到数据库中。思路如下:
  (1)添加一个唯一属性字段,可以标识数据库表中的新闻,例如jinse+bottomId构成唯一属性,或者新闻的具体页面路径URI构成唯一属性。
  (2)创建地图集合,通过URI查看数据库是否存在,如果存在,则不存在。
  (3)存储前,如果为false则通过map.get(URI),然后存储到数据库中。
  git 源代码
  首先说明一下,源码本身通过了Idea测试,这里使用的是lombok。你现在需要为idea或eclipse配置Lombok。
  源地址:
  想的太多,做的太少,中间的差距就是麻烦。如果您不想担心,请不要考虑或做更多。中校【9】 查看全部

  java爬虫抓取动态网页(爬虫+基于接口的网络爬虫(爬虫爬虫)(组图))
  爬虫+基于接口的网络爬虫
  上一篇讲了【java爬虫】---爬虫+jsoup轻松爬取博客。这种方法有一个很大的局限性,就是只能通过jsoup爬虫爬取静态网页,所以只能爬取当前页面上的所有新闻。如果需要爬取一个网站的所有信息,就需要通过接口反复调整网站的接口,通过改变参数来爬取网站@的所有数据信息&gt;.
  本博客旨在抓取黄金财经新闻资讯,抓取网站自建站以来发布的所有新闻资讯。下面将分步说明。这里重点讲一下思路,最后提供完整的源码。
  第一步:找到界面
  如果要获取这个网站的所有新闻数据,第一步当然是获取接口,通过接口获取所有信息。
  F12--&gt;网络--&gt;全部,找到界面:
  这三个参数的说明:
  limit=23 表示每次调用接口返回23条数据。
  information_id=56630 表示下面返回的23条数据是通过大于56630或小于56630的ID指纹返回的。
  flag=down 表示向下翻页。这里指的是23条ID小于56630的数据。
  通过邮递员测试
  输入:(这里返回两条,这里id=0代表最新的两条数据)
  返回json数据格式:
  
  接口返回信息
  第二步:通过定时任务启动爬虫工作
  @Slf4j
@Component
public class SchedulePressTrigger {
@Autowired
private CrawlerJinSeLivePressService crawlerJinSeLivePressService;
/**
* 定时抓取金色财经的新闻
*/
@Scheduled(initialDelay = 1000, fixedRate = 600 * 1000)
public void doCrawlJinSeLivePress() {
// log.info("开始抓取金色财经新闻, time:" + new Date());
try {
crawlerJinSeLivePressService.start();
} catch (Exception e) {
// log.error("本次抓取金色财经新闻异常", e);
}
// log.info("结束抓取金色财经新闻, time:" + new Date());
}
}
  第三步:主要实现类
  /**
* 抓取金色财经快讯
* @author xub
* @since 2018/6/29
*/
@Slf4j
@Service
public class CrawlerJinSeLivePressServiceImpl extends AbstractCrawlLivePressService implements
CrawlerJinSeLivePressService {
//这个参数代表每一次请求获得多少个数据
private static final int PAGE_SIZE = 15;
//这个是真正翻页参数,每一次找id比它小的15个数据(有写接口是通过page=1,2来进行翻页所以比较好理解一点,其实它们性质一样)
private long bottomId;
//这个这里没有用到,但是如果有数据层,就需要用到,这里我只是把它答应到控制台
@Autowired
private LivePressService livePressService;



//定时任务运行这个方法,doTask没有被重写,所有运行父类的方法
@Override
public void start() {
try {
doTask(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT);
} catch (IOException e) {
// log.error("抓取金色财经新闻异常", e);
}
}
@Override
protected List crawlPage(int pageNum) throws IOException {
// 最多抓取100页,多抓取也没有特别大的意思。
if (pageNum >= 100) {
return Collections.emptyList();
}
// 格式化翻页参数(第一次bottomId为0,第二次就是这次爬到的最小bottomId值)
String requestUrl = String.format(CoinPressConsts.CHAIN_FOR_LIVE_PRESS_DATA_URL_FORMAT, PAGE_SIZE, bottomId);
Response response = OkHttp.singleton().newCall(
new Request.Builder().url(requestUrl).addHeader("referer", CoinPressConsts.CHAIN_FOR_LIVE_URL).get().build())
.execute();
if (response.isRedirect()) {
// 如果请求发生了跳转,说明请求不是原来的地址了,返回空数据。
return Collections.emptyList();
}
//先获得json数据格式
String responseText = response.body().string();
//在通过工具类进行数据赋值
JinSePressResult jinSepressResult = JsonUtils.objectFromJson(responseText, JinSePressResult.class);
if (null == jinSepressResult) {
// 反序列化失败
System.out.println("抓取金色财经新闻列表反序列化异常");
return Collections.emptyList();
}
// 取金色财经最小的记录id,来进行翻页
bottomId = jinSepressResult.getBottomId();
//这个是谷歌提供了guava包里的工具类,Lists这个集合工具,对list集合操作做了些优化提升。
List pageListPresss = Lists.newArrayListWithExpectedSize(PAGE_SIZE);
for (JinSePressResult.DayData dayData : jinSepressResult.getList()) {
JinSePressData data = dayData.getExtra();
//新闻发布时间(时间戳格式)这里可以来判断只爬多久时间以内的新闻
long createTime = data.getPublishedAt() * 1000;
Long timemill=System.currentTimeMillis();
// if (System.currentTimeMillis() - createTime > CoinPressConsts.MAX_CRAWLER_TIME) {
// // 快讯过老了,放弃
// continue;
// }
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sd = sdf.format(new Date(createTime)); // 时间戳转换成时间
Date newsCreateTime=new Date();
try {
//获得新闻发布时间
newsCreateTime = sdf.parse(sd);
} catch (ParseException e) {
e.printStackTrace();
}
//具体文章页面路径(这里可以通过这个路径+jsoup就可以爬新闻正文所有信息了)
String href = data.getTopicUrl();
//新闻摘要
String summary = data.getSummary();
//新闻阅读数量
String pressreadcount = data.getReadNumber();
//新闻标题
String title = dayData.getTitle();
pageListPresss.add(new PageListPress(href,title, Integer.parseInt(pressreadcount),
newsCreateTime , summary));
}
return pageListPresss;
}
}
  AbstractCrawlLivePressService 类
   public abstract class AbstractCrawlLivePressService {
String url;
public void doTask(String url) throws IOException {
this.url = url;
int pageNum = 1;
//通过 while (true)会一直循环调取接口,直到数据为空或者时间过老跳出循环
while (true) {
List newsList = crawlPage(pageNum++);
// 抓取不到新的内容本次抓取结束
if (CollectionUtils.isEmpty(newsList)) {
break;
}
//这里并没有把数据放到数据库,而是直接从控制台输出
for (int i = newsList.size() - 1; i >= 0; i--) {
PageListPress pageListNews = newsList.get(i);
System.out.println(pageListNews.toString());

}
}
}
//这个由具体实现类实现
protected abstract List crawlPage(int pageNum) throws IOException;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class PageListPress {
//新闻详情页面url
private String href;
//新闻标题
private String title;
//新闻阅读数量
private int readCounts;
//新闻发布时间
private Date createTime;
//新闻摘要
private String summary;

}
}
  锦色印刷结果
  /**
*在创建对象的时候一定要分析好json格式的类型
*金色新闻的返回格式就是第一层有普通属性和一个list集合
*在list集合中又有普通属性和一个extra的对象。
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class JinSePressResult {
private int news;
private int count;
@JsonProperty("top_id")
private long topId;
@JsonProperty("bottom_id")
private long bottomId;
//list的名字也要和json数据的list名字一致,否则无用
private List list;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class DayData {
private String title;
//这里对象的属性名extra也要和json的extra名字一致
private JinSePressData extra;
@JsonProperty("topic_url")
private String topicUrl;
}
}
  这里有两点需要注意
  (1) 创建对象时,首先要弄清楚json格式类型是否收录对象中的集合,或者集合中是否有对象等。
  (2) 只能定义自己需要的属性字段。当无法匹配json的属性名但类型不一致时,比如上面改成Listextra,序列化就会失败,因为json的extra明明是一个Object,这里接受的确实是一个集合。关键是要属于
  性别名称相同,所以赋值时会报错,序列化失败。
  第四步:查看操作结果
  这只是截取了控制台输出的部分信息。这样就可以得到网站的所有新闻信息。同时我们已经获取到了具体新闻的URL,那么我们就可以通过JSOup获取到该新闻的所有具体信息了。(完美的)
  
  第五步:数据库去重思路
  因为你不可能每次爬取都直接把播放数据放到数据库中,所以必须比较新闻数据库是否已经存在,如果不存在就放到数据库中。思路如下:
  (1)添加一个唯一属性字段,可以标识数据库表中的新闻,例如jinse+bottomId构成唯一属性,或者新闻的具体页面路径URI构成唯一属性。
  (2)创建地图集合,通过URI查看数据库是否存在,如果存在,则不存在。
  (3)存储前,如果为false则通过map.get(URI),然后存储到数据库中。
  git 源代码
  首先说明一下,源码本身通过了Idea测试,这里使用的是lombok。你现在需要为idea或eclipse配置Lombok。
  源地址:
  想的太多,做的太少,中间的差距就是麻烦。如果您不想担心,请不要考虑或做更多。中校【9】

java爬虫抓取动态网页(深入剖析Python爬虫框架的结构与运作流程的相关内容)

网站优化优采云 发表了文章 • 0 个评论 • 51 次浏览 • 2021-12-07 19:06 • 来自相关话题

  java爬虫抓取动态网页(深入剖析Python爬虫框架的结构与运作流程的相关内容)
  想了解深入解析Python爬虫框架Scrapy的结构和运行过程吗?在本文中,pluskid将为大家仔细讲解Scrapy框架的结构和运行过程以及一些代码示例。欢迎阅读指正,先重点说一下:Python、Scrapy、爬虫,一起学习。
  网络爬虫(Spider)是一种在互联网上爬行的机器人。当然,它通常不是实体机器人,因为网络本身也是一个虚拟的东西,所以这个“机器人”其实就是一个程序,不是爬行,而是有一定的用途,爬行的时候会采集. 一些信息。例如,谷歌有很多爬虫采集网页内容和它们之间的链接信息;另一个例子是别有用心的爬虫在互联网上采集诸如foo [at] bar [dot] com之类的东西。此外,还有一些定制的爬虫,专门针对某个网站。比如JavaEye的Robbin前段时间写了几篇专门对付恶意爬虫的博客。是的)和 网站 诸如小众软件或 LinuxToy 之类的软件通常会被整个站点抓取下来并以不同的名称挂出。其实,爬虫的基本原理非常简单。只要能上网,能分析网页,现在大多数语言都有方便的Http客户端库可以抓取网页,最简单的HTML分析可以直接使用正则规则。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。然而,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。
  爬虫的两部分是下载网页。需要考虑的问题有很多,比如如何最大限度地利用本地带宽,如何调度不同站点的web请求,以减少其他服务器的负担。在高性能的Web Crawler系统中,DNS查询也将成为亟待优化的瓶颈。此外,还有一些“配置文件”需要遵循(例如,robots.txt)。获取网页后的分析过程也很复杂。网上奇奇怪怪的东西很多,各种HTML页面出现各种错误。分析所有这些几乎是不可能的。另外,随着AJAX的普及,如何获取Javascript动态生成的内容成为了一个大问题;此外,互联网上有各种有意或无意出现的蜘蛛陷阱。如果一味的跟着超链接走,就会被困在陷阱里。比如,这个网站据说是谷歌之前宣布互联网上Unique URL的数量已经达到1万亿,所以这个人很自豪的宣布第二万亿。:D
  然而,实际上并没有多少人需要像谷歌这样的通用爬虫。通常我们构建一个爬虫来爬取一个特定的或者某个类型的网站,所谓知己知彼,百战不死,我们可以提前爬取对网站做一些分析网站 结构,事情变得容易多了。通过分析和选择有价值的链接进行跟踪,我们可以避免很多不必要的链接或蜘蛛陷阱。如果网站的结构允许选择合适的路径,我们就可以按照感兴趣的事物的一定顺序再次爬取它,这样就连URL重复的判断都可以省略了。
  比如我们要爬下pongba博客中的博客文字,通过观察,很容易发现我们对其中两个页面感兴趣:
  文章列表页面,比如首页,或者URL为/page/\d+/的页面,通过Firebug可以看到每个文章链接都在h1下的一个标签中(应该是注意Firebug的HTML面板看到的HTML代码可能和View Source看到的有些不同,如果网页中有动态修改DOM树的Javascript,前者是修改后的版本,Firebug正则化后,比如属性有引号等等,后者通常是你的蜘蛛爬取的原创内容,如果你用正则表达式分析页面或者使用的HTML Parser和Firefox有些不同,(需要特别注意). 另外,在一个类为 wp-pagenavi 的 div 中有指向不同列表页面的链接。
  文章 内容页,每个博客都有这样一个页面,比如/2008/09/11/machine-learning-and-ai-resources/,收录了文章的完整内容,这是我们的感受感兴趣的内容。
  因此,我们从首页开始,利用 wp-pagenavi 中的链接来获取其他 文章 列表页面。特别是我们定义了一个路径:只跟随Next Page的链接,这样我们就可以从头到尾依次进行一遍,省去了反复爬行判断的麻烦。另外,文章列表页上链接到具体文章的链接对应的页面就是我们真正要保存的数据页。
  这样,它实用的脚本语言写一个ad hoc爬虫来完成这个任务并不难,不过今天的主角是Scrapy,它是一个用Python编写的爬虫框架,简单轻量,非常方便,官网说已经在实际生产中使用过,所以不是玩具级别的东西。但是,目前还没有 Release 版本。您可以直接使用其 Mercurial 存储库中的源代码来安装它。不过这个东西也可以不安装直接使用,方便随时更新。文档很详细,不再赘述。
  Scrapy 使用异步网络库 Twisted 来处理网络通信。架构清晰,收录各种中间件接口,可以灵活满足各种需求。整体架构如下图所示:
  
  绿线是数据流向。从最初的URL开始,Scheduler将其交给Downloader进行下载,下载完成后交给Spider进行分析。Spider分析的结果有两种:一种是需要进一步爬取的链接。比如之前分析的“下一页”的链接,这些东西会被发回给Scheduler;另一个是需要保存的数据,发送到Item Pipeline,就是数据的后处理(详细分析、过滤、存储等)。此外,可以在数据流通道中安装各种中间件来进行必要的处理。
  具体内容将在上一个附件中介绍。
  它看起来很复杂,但使用起来非常简单。就像Rails一样,首先新建一个项目:
  
scrapy-admin.py startproject blog_crawl
  会创建一个blog_crawl目录,里面有一个scrapy-ctl.py是整个项目的控制脚本,代码全部放在子目录blog_crawl下。为了能够爬取,我们在spiders目录下新建一个mindhacks_spider.py,定义我们的Spider如下:
  
from scrapy.spider import BaseSpider

class MindhacksSpider(BaseSpider):
domain_name = "mindhacks.cn"
start_urls = ["http://mindhacks.cn/"]

def parse(self, response):
return []

SPIDER = MindhacksSpider()
  我们的MindhacksSpider继承自BaseSpider(通常直接来自scrapy.contrib.spiders.CrawlSpider,它更通用,更方便,但是为了展示数据是如何解析的,这里使用了BaseSpider),变量domain_name和start_urls是容易理解是什么意思,parse方法就是我们需要定义的回调函数。默认请求在得到响应后会调用这个回调函数。这里我们需要解析页面,返回两个结果(需要进一步爬取链接,需要保存Data)。让我觉得有点奇怪的是,它的接口定义中的两个结果居然混在一个列表中返回。我不知道为什么它是这样设计的。最后不是要把他们分开吗?总之,这里我们先写一个空函数,它只返回一个空列表。另外,定义一个“全局”变量 SPIDER,它会在 Scrapy 导入这个模块时被实例化,并且会被 Scrapy 引擎自动找到。所以你可以先运行爬虫试试:
  
./scrapy-ctl.py crawl mindhacks.cn
  会有一堆输出,可以看到爬取了,因为这是初始的URL,但是因为我们在parse函数中没有返回需要进一步爬取的URL,所以整个爬取过程只爬取了首页和结束了。下一步是分析页面。Scrapy 提供了一个非常方便的Shell(需要IPython),可以让我们做实验。使用以下命令启动 Shell:
  
./scrapy-ctl.py shell http://mindhacks.cn
  它会启动爬虫,抓取命令行指定的页面,然后进入shell。根据提示,我们有很多现成的变量可以使用。其中之一是 hxs,它是一个 HtmlXPathSelector。mindhacks 的 HTML 页面是比较标准的。直接用XPath分析非常方便。通过Firebug可以看到每个博客文章的链接都在h1下,所以在Shell中使用这个XPath表达式测试:
  
In [1]: hxs.x('//h1/a/@href').extract()
Out[1]:
[u'http://mindhacks.cn/2009/07/06/why-you-should-do-it-yourself/',
u'http://mindhacks.cn/2009/05/17/seven-years-in-nju/',
u'http://mindhacks.cn/2009/03/28/effective-learning-and-memorization/',
u'http://mindhacks.cn/2009/03/15/preconception-explained/',
u'http://mindhacks.cn/2009/03/09/first-principles-of-programming/',
u'http://mindhacks.cn/2009/02/15/why-you-should-start-blogging-now/',
u'http://mindhacks.cn/2009/02/09/writing-is-better-thinking/',
u'http://mindhacks.cn/2009/02/07/better-explained-conflicts-in-intimate-relationship/',
u'http://mindhacks.cn/2009/02/07/independence-day/',
u'http://mindhacks.cn/2009/01/18/escape-from-your-shawshank-part1/']
  这正是我们需要的 URL。另外可以找到“下一页”的链接,和其他几个页面的链接放在一个div里,但是“下一页”的链接没有title属性,所以写XPath
  
//div[@class="wp-pagenavi"]/a[not(@title)]
  但是,如果你往回翻一页,你会发现“上一页”其实是一样的,所以你需要确定链接上的文字是下一页的箭头u'\xbb',这可能有是用 XPath 编写的。去,不过好像这本身就是一个unicode转义字符,由于编码原因不清楚,直接在外面判断,最终解析函数如下:
  
def parse(self, response):
items = []
hxs = HtmlXPathSelector(response)
posts = hxs.x('//h1/a/@href').extract()
items.extend([self.make_requests_from_url(url).replace(callback=self.parse_post)
for url in posts])

page_links = hxs.x('//div[@class="wp-pagenavi"]/a[not(@title)]')
for link in page_links:
if link.x('text()').extract()[0] == u'\xbb':
url = link.x('@href').extract()[0]
items.append(self.make_requests_from_url(url))

return items
  前半部分是解析需要爬取的博客正文的链接,后半部分是给出“下一页”的链接。需要注意的是,这里返回的列表并非都是字符串格式的URL。Scrapy希望得到的是Request对象,它可以携带比字符串格式的URL更多的东西,比如cookies或者回调。功能等。可以看到我们在创建博客正文的请求时替换了回调函数,因为默认的回调函数parse是专门用来解析文章列表等页面的,parse_post定义如下:
  
def parse_post(self, response):
item = BlogCrawlItem()
item.url = unicode(response.url)
item.raw = response.body_as_unicode()
return [item]
  这很简单。返回一个 BlogCrawlItem 并将捕获的数据放入其中。你可以在这里做一些分析。比如你可以通过XPath来解析文本和标题,但是我倾向于后期做这些事情,比如Item Pipeline或者Later Offline stage。BlogCrawlItem 是 Scrapy 自动为我们定义的一个空类,继承自 ScrapedItem。在 items.py 中,我在这里添加了一些东西:
  
from scrapy.item import ScrapedItem

class BlogCrawlItem(ScrapedItem):
def __init__(self):
ScrapedItem.__init__(self)
self.url = ''

def __str__(self):
return 'BlogCrawlItem(url: %s)' % self.url
  定义了__str__函数,只给出了URL,因为默认的__str__函数会显示所有的数据,所以看到爬取的时候,控制台日志会输出一些东西,就是把爬取到的网页的内容输出出来。-.-bb
  这样,数据就被取出来了,最后只剩下存储数据的功能了。我们通过添加流水线来实现它。由于Python在标准库中自带Sqlite3支持,所以我使用Sqlite数据库来存储数据。将 pipelines.py 的内容替换为以下代码:
  
import sqlite3
from os import path

from scrapy.core import signals
from scrapy.xlib.pydispatch import dispatcher

class SQLiteStorePipeline(object):
filename = 'data.sqlite'

def __init__(self):
self.conn = None
dispatcher.connect(self.initialize, signals.engine_started)
dispatcher.connect(self.finalize, signals.engine_stopped)

def process_item(self, domain, item):
self.conn.execute('insert into blog values(?,?,?)',
(item.url, item.raw, unicode(domain)))
return item

def initialize(self):
if path.exists(self.filename):
self.conn = sqlite3.connect(self.filename)
else:
self.conn = self.create_table(self.filename)

def finalize(self):
if self.conn is not None:
self.conn.commit()
self.conn.close()
self.conn = None

def create_table(self, filename):
conn = sqlite3.connect(filename)
conn.execute("""create table blog
(url text primary key, raw text, domain text)""")
conn.commit()
return conn
  在__init__函数中,使用dispatcher将两个信号连接到指定的函数,用于初始化和关闭数据库连接(记得关闭前commit,好像不会自动commit,如果直接关闭的话,似乎所有数据都是 Dd-.-) 丢失。当数据通过管道时,将调用 process_item 函数。这里我们将原创数据直接存入数据库,不做任何处理。如有必要,您可以添加额外的管道来提取和过滤数据,但我不会在这里详细介绍。
  最后,在 settings.py 中列出我们的管道:
  ITEM_PIPELINES = ['blog_crawl.pipelines.SQLiteStorePipeline']
  再次运行爬虫就OK了!
  PS1:Scrapy 组件
  1.Scrapy 引擎(Scrapy 引擎)
  Scrapy 引擎用于控制整个系统的数据处理流程并触发事务处理。更多详细信息,请参见以下数据处理流程。
  2.调度器(调度器)
  调度器接受来自 Scrapy 引擎的请求并将它们排序到队列中,并在 Scrapy 引擎发送请求后将它们返回给它们。
  3.下载器(下载器)
  下载器的主要职责是抓取网页并将网页内容返回给蜘蛛。
  4.蜘蛛(蜘蛛)
  Spiders 是 Scrapy 用户定义的类,用于解析网页并抓取指定 URL 返回的内容。每个蜘蛛可以处理一个域名或一组域名。换句话说,它用于定义特定的网站 爬取和解析规则。
  5.项目管道(项目管道)
  项目管道的主要职责是处理蜘蛛从网页中提取的项目。它的主要任务是澄清、验证和存储数据。当页面被蜘蛛解析后,会被发送到项目管道,数据会按照几个特定的​​顺序进行处理。每个项目管道的组件都是具有简单方法的 Python 类。他们获得项目并执行他们的方法,他们还需要确定是否需要继续进行项目管道的下一步,或者干脆将其丢弃而不进行处理。
  项目管道通常执行的过程是:
  清理HTML数据,验证解析数据(检查item是否收录必要的字段) 检查数据是否重复(如果重复则删除) 将解析数据存入数据库
  6.中间件(Middleware)
  中间件是 Scrapy 引擎和其他组件之间的一个钩子框架,主要是提供自定义代码来扩展 Scrapy 的功能。
  PS2:Scrapy的数据处理流程
  Scrapy整个数据处理流程由Scrapy引擎控制,其主要运行方式为:
  当引擎打开一个域名时,蜘蛛会对该域名进行处理,并要求蜘蛛获取爬取的第一个 URL。
  引擎从蜘蛛那里获取第一个需要爬取的URL,然后在调度中作为请求进行调度。
  引擎从调度程序获取接下来要抓取的页面。
  调度器将下一个爬取到的URL返回给引擎,引擎通过下载中间件发送给下载器。
  当下载器下载网页时,响应内容通过下载中间件发送给引擎。
  引擎接收下载器的响应,通过蜘蛛中间件发送给蜘蛛进行处理。
  蜘蛛处理响应并返回爬取的项目,然后向引擎发送新请求。
  引擎将抓取项目管道并向调度员发送请求。
  系统重复第二部分之后的操作,直到调度中没有请求,然后断开引擎和域之间的连接。
  相关文章 查看全部

  java爬虫抓取动态网页(深入剖析Python爬虫框架的结构与运作流程的相关内容)
  想了解深入解析Python爬虫框架Scrapy的结构和运行过程吗?在本文中,pluskid将为大家仔细讲解Scrapy框架的结构和运行过程以及一些代码示例。欢迎阅读指正,先重点说一下:Python、Scrapy、爬虫,一起学习。
  网络爬虫(Spider)是一种在互联网上爬行的机器人。当然,它通常不是实体机器人,因为网络本身也是一个虚拟的东西,所以这个“机器人”其实就是一个程序,不是爬行,而是有一定的用途,爬行的时候会采集. 一些信息。例如,谷歌有很多爬虫采集网页内容和它们之间的链接信息;另一个例子是别有用心的爬虫在互联网上采集诸如foo [at] bar [dot] com之类的东西。此外,还有一些定制的爬虫,专门针对某个网站。比如JavaEye的Robbin前段时间写了几篇专门对付恶意爬虫的博客。是的)和 网站 诸如小众软件或 LinuxToy 之类的软件通常会被整个站点抓取下来并以不同的名称挂出。其实,爬虫的基本原理非常简单。只要能上网,能分析网页,现在大多数语言都有方便的Http客户端库可以抓取网页,最简单的HTML分析可以直接使用正则规则。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。然而,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。表达式做到了,所以做最简单的网络爬虫其实是一件很简单的事情。但是,要实现一个高质量的蜘蛛是非常困难的。
  爬虫的两部分是下载网页。需要考虑的问题有很多,比如如何最大限度地利用本地带宽,如何调度不同站点的web请求,以减少其他服务器的负担。在高性能的Web Crawler系统中,DNS查询也将成为亟待优化的瓶颈。此外,还有一些“配置文件”需要遵循(例如,robots.txt)。获取网页后的分析过程也很复杂。网上奇奇怪怪的东西很多,各种HTML页面出现各种错误。分析所有这些几乎是不可能的。另外,随着AJAX的普及,如何获取Javascript动态生成的内容成为了一个大问题;此外,互联网上有各种有意或无意出现的蜘蛛陷阱。如果一味的跟着超链接走,就会被困在陷阱里。比如,这个网站据说是谷歌之前宣布互联网上Unique URL的数量已经达到1万亿,所以这个人很自豪的宣布第二万亿。:D
  然而,实际上并没有多少人需要像谷歌这样的通用爬虫。通常我们构建一个爬虫来爬取一个特定的或者某个类型的网站,所谓知己知彼,百战不死,我们可以提前爬取对网站做一些分析网站 结构,事情变得容易多了。通过分析和选择有价值的链接进行跟踪,我们可以避免很多不必要的链接或蜘蛛陷阱。如果网站的结构允许选择合适的路径,我们就可以按照感兴趣的事物的一定顺序再次爬取它,这样就连URL重复的判断都可以省略了。
  比如我们要爬下pongba博客中的博客文字,通过观察,很容易发现我们对其中两个页面感兴趣:
  文章列表页面,比如首页,或者URL为/page/\d+/的页面,通过Firebug可以看到每个文章链接都在h1下的一个标签中(应该是注意Firebug的HTML面板看到的HTML代码可能和View Source看到的有些不同,如果网页中有动态修改DOM树的Javascript,前者是修改后的版本,Firebug正则化后,比如属性有引号等等,后者通常是你的蜘蛛爬取的原创内容,如果你用正则表达式分析页面或者使用的HTML Parser和Firefox有些不同,(需要特别注意). 另外,在一个类为 wp-pagenavi 的 div 中有指向不同列表页面的链接。
  文章 内容页,每个博客都有这样一个页面,比如/2008/09/11/machine-learning-and-ai-resources/,收录了文章的完整内容,这是我们的感受感兴趣的内容。
  因此,我们从首页开始,利用 wp-pagenavi 中的链接来获取其他 文章 列表页面。特别是我们定义了一个路径:只跟随Next Page的链接,这样我们就可以从头到尾依次进行一遍,省去了反复爬行判断的麻烦。另外,文章列表页上链接到具体文章的链接对应的页面就是我们真正要保存的数据页。
  这样,它实用的脚本语言写一个ad hoc爬虫来完成这个任务并不难,不过今天的主角是Scrapy,它是一个用Python编写的爬虫框架,简单轻量,非常方便,官网说已经在实际生产中使用过,所以不是玩具级别的东西。但是,目前还没有 Release 版本。您可以直接使用其 Mercurial 存储库中的源代码来安装它。不过这个东西也可以不安装直接使用,方便随时更新。文档很详细,不再赘述。
  Scrapy 使用异步网络库 Twisted 来处理网络通信。架构清晰,收录各种中间件接口,可以灵活满足各种需求。整体架构如下图所示:
  
  绿线是数据流向。从最初的URL开始,Scheduler将其交给Downloader进行下载,下载完成后交给Spider进行分析。Spider分析的结果有两种:一种是需要进一步爬取的链接。比如之前分析的“下一页”的链接,这些东西会被发回给Scheduler;另一个是需要保存的数据,发送到Item Pipeline,就是数据的后处理(详细分析、过滤、存储等)。此外,可以在数据流通道中安装各种中间件来进行必要的处理。
  具体内容将在上一个附件中介绍。
  它看起来很复杂,但使用起来非常简单。就像Rails一样,首先新建一个项目:
  
scrapy-admin.py startproject blog_crawl
  会创建一个blog_crawl目录,里面有一个scrapy-ctl.py是整个项目的控制脚本,代码全部放在子目录blog_crawl下。为了能够爬取,我们在spiders目录下新建一个mindhacks_spider.py,定义我们的Spider如下:
  
from scrapy.spider import BaseSpider

class MindhacksSpider(BaseSpider):
domain_name = "mindhacks.cn"
start_urls = ["http://mindhacks.cn/"]

def parse(self, response):
return []

SPIDER = MindhacksSpider()
  我们的MindhacksSpider继承自BaseSpider(通常直接来自scrapy.contrib.spiders.CrawlSpider,它更通用,更方便,但是为了展示数据是如何解析的,这里使用了BaseSpider),变量domain_name和start_urls是容易理解是什么意思,parse方法就是我们需要定义的回调函数。默认请求在得到响应后会调用这个回调函数。这里我们需要解析页面,返回两个结果(需要进一步爬取链接,需要保存Data)。让我觉得有点奇怪的是,它的接口定义中的两个结果居然混在一个列表中返回。我不知道为什么它是这样设计的。最后不是要把他们分开吗?总之,这里我们先写一个空函数,它只返回一个空列表。另外,定义一个“全局”变量 SPIDER,它会在 Scrapy 导入这个模块时被实例化,并且会被 Scrapy 引擎自动找到。所以你可以先运行爬虫试试:
  
./scrapy-ctl.py crawl mindhacks.cn
  会有一堆输出,可以看到爬取了,因为这是初始的URL,但是因为我们在parse函数中没有返回需要进一步爬取的URL,所以整个爬取过程只爬取了首页和结束了。下一步是分析页面。Scrapy 提供了一个非常方便的Shell(需要IPython),可以让我们做实验。使用以下命令启动 Shell:
  
./scrapy-ctl.py shell http://mindhacks.cn
  它会启动爬虫,抓取命令行指定的页面,然后进入shell。根据提示,我们有很多现成的变量可以使用。其中之一是 hxs,它是一个 HtmlXPathSelector。mindhacks 的 HTML 页面是比较标准的。直接用XPath分析非常方便。通过Firebug可以看到每个博客文章的链接都在h1下,所以在Shell中使用这个XPath表达式测试:
  
In [1]: hxs.x('//h1/a/@href').extract()
Out[1]:
[u'http://mindhacks.cn/2009/07/06/why-you-should-do-it-yourself/',
u'http://mindhacks.cn/2009/05/17/seven-years-in-nju/',
u'http://mindhacks.cn/2009/03/28/effective-learning-and-memorization/',
u'http://mindhacks.cn/2009/03/15/preconception-explained/',
u'http://mindhacks.cn/2009/03/09/first-principles-of-programming/',
u'http://mindhacks.cn/2009/02/15/why-you-should-start-blogging-now/',
u'http://mindhacks.cn/2009/02/09/writing-is-better-thinking/',
u'http://mindhacks.cn/2009/02/07/better-explained-conflicts-in-intimate-relationship/',
u'http://mindhacks.cn/2009/02/07/independence-day/',
u'http://mindhacks.cn/2009/01/18/escape-from-your-shawshank-part1/']
  这正是我们需要的 URL。另外可以找到“下一页”的链接,和其他几个页面的链接放在一个div里,但是“下一页”的链接没有title属性,所以写XPath
  
//div[@class="wp-pagenavi"]/a[not(@title)]
  但是,如果你往回翻一页,你会发现“上一页”其实是一样的,所以你需要确定链接上的文字是下一页的箭头u'\xbb',这可能有是用 XPath 编写的。去,不过好像这本身就是一个unicode转义字符,由于编码原因不清楚,直接在外面判断,最终解析函数如下:
  
def parse(self, response):
items = []
hxs = HtmlXPathSelector(response)
posts = hxs.x('//h1/a/@href').extract()
items.extend([self.make_requests_from_url(url).replace(callback=self.parse_post)
for url in posts])

page_links = hxs.x('//div[@class="wp-pagenavi"]/a[not(@title)]')
for link in page_links:
if link.x('text()').extract()[0] == u'\xbb':
url = link.x('@href').extract()[0]
items.append(self.make_requests_from_url(url))

return items
  前半部分是解析需要爬取的博客正文的链接,后半部分是给出“下一页”的链接。需要注意的是,这里返回的列表并非都是字符串格式的URL。Scrapy希望得到的是Request对象,它可以携带比字符串格式的URL更多的东西,比如cookies或者回调。功能等。可以看到我们在创建博客正文的请求时替换了回调函数,因为默认的回调函数parse是专门用来解析文章列表等页面的,parse_post定义如下:
  
def parse_post(self, response):
item = BlogCrawlItem()
item.url = unicode(response.url)
item.raw = response.body_as_unicode()
return [item]
  这很简单。返回一个 BlogCrawlItem 并将捕获的数据放入其中。你可以在这里做一些分析。比如你可以通过XPath来解析文本和标题,但是我倾向于后期做这些事情,比如Item Pipeline或者Later Offline stage。BlogCrawlItem 是 Scrapy 自动为我们定义的一个空类,继承自 ScrapedItem。在 items.py 中,我在这里添加了一些东西:
  
from scrapy.item import ScrapedItem

class BlogCrawlItem(ScrapedItem):
def __init__(self):
ScrapedItem.__init__(self)
self.url = ''

def __str__(self):
return 'BlogCrawlItem(url: %s)' % self.url
  定义了__str__函数,只给出了URL,因为默认的__str__函数会显示所有的数据,所以看到爬取的时候,控制台日志会输出一些东西,就是把爬取到的网页的内容输出出来。-.-bb
  这样,数据就被取出来了,最后只剩下存储数据的功能了。我们通过添加流水线来实现它。由于Python在标准库中自带Sqlite3支持,所以我使用Sqlite数据库来存储数据。将 pipelines.py 的内容替换为以下代码:
  
import sqlite3
from os import path

from scrapy.core import signals
from scrapy.xlib.pydispatch import dispatcher

class SQLiteStorePipeline(object):
filename = 'data.sqlite'

def __init__(self):
self.conn = None
dispatcher.connect(self.initialize, signals.engine_started)
dispatcher.connect(self.finalize, signals.engine_stopped)

def process_item(self, domain, item):
self.conn.execute('insert into blog values(?,?,?)',
(item.url, item.raw, unicode(domain)))
return item

def initialize(self):
if path.exists(self.filename):
self.conn = sqlite3.connect(self.filename)
else:
self.conn = self.create_table(self.filename)

def finalize(self):
if self.conn is not None:
self.conn.commit()
self.conn.close()
self.conn = None

def create_table(self, filename):
conn = sqlite3.connect(filename)
conn.execute("""create table blog
(url text primary key, raw text, domain text)""")
conn.commit()
return conn
  在__init__函数中,使用dispatcher将两个信号连接到指定的函数,用于初始化和关闭数据库连接(记得关闭前commit,好像不会自动commit,如果直接关闭的话,似乎所有数据都是 Dd-.-) 丢失。当数据通过管道时,将调用 process_item 函数。这里我们将原创数据直接存入数据库,不做任何处理。如有必要,您可以添加额外的管道来提取和过滤数据,但我不会在这里详细介绍。
  最后,在 settings.py 中列出我们的管道:
  ITEM_PIPELINES = ['blog_crawl.pipelines.SQLiteStorePipeline']
  再次运行爬虫就OK了!
  PS1:Scrapy 组件
  1.Scrapy 引擎(Scrapy 引擎)
  Scrapy 引擎用于控制整个系统的数据处理流程并触发事务处理。更多详细信息,请参见以下数据处理流程。
  2.调度器(调度器)
  调度器接受来自 Scrapy 引擎的请求并将它们排序到队列中,并在 Scrapy 引擎发送请求后将它们返回给它们。
  3.下载器(下载器)
  下载器的主要职责是抓取网页并将网页内容返回给蜘蛛。
  4.蜘蛛(蜘蛛)
  Spiders 是 Scrapy 用户定义的类,用于解析网页并抓取指定 URL 返回的内容。每个蜘蛛可以处理一个域名或一组域名。换句话说,它用于定义特定的网站 爬取和解析规则。
  5.项目管道(项目管道)
  项目管道的主要职责是处理蜘蛛从网页中提取的项目。它的主要任务是澄清、验证和存储数据。当页面被蜘蛛解析后,会被发送到项目管道,数据会按照几个特定的​​顺序进行处理。每个项目管道的组件都是具有简单方法的 Python 类。他们获得项目并执行他们的方法,他们还需要确定是否需要继续进行项目管道的下一步,或者干脆将其丢弃而不进行处理。
  项目管道通常执行的过程是:
  清理HTML数据,验证解析数据(检查item是否收录必要的字段) 检查数据是否重复(如果重复则删除) 将解析数据存入数据库
  6.中间件(Middleware)
  中间件是 Scrapy 引擎和其他组件之间的一个钩子框架,主要是提供自定义代码来扩展 Scrapy 的功能。
  PS2:Scrapy的数据处理流程
  Scrapy整个数据处理流程由Scrapy引擎控制,其主要运行方式为:
  当引擎打开一个域名时,蜘蛛会对该域名进行处理,并要求蜘蛛获取爬取的第一个 URL。
  引擎从蜘蛛那里获取第一个需要爬取的URL,然后在调度中作为请求进行调度。
  引擎从调度程序获取接下来要抓取的页面。
  调度器将下一个爬取到的URL返回给引擎,引擎通过下载中间件发送给下载器。
  当下载器下载网页时,响应内容通过下载中间件发送给引擎。
  引擎接收下载器的响应,通过蜘蛛中间件发送给蜘蛛进行处理。
  蜘蛛处理响应并返回爬取的项目,然后向引擎发送新请求。
  引擎将抓取项目管道并向调度员发送请求。
  系统重复第二部分之后的操作,直到调度中没有请求,然后断开引擎和域之间的连接。
  相关文章

java爬虫抓取动态网页(爬虫多IP抓取怎么获取大量IP?方法有哪些?)

网站优化优采云 发表了文章 • 0 个评论 • 46 次浏览 • 2021-12-06 16:19 • 来自相关话题

  java爬虫抓取动态网页(爬虫多IP抓取怎么获取大量IP?方法有哪些?)
  网络爬虫如何获取大量动态IP进行数据抓取?通常在爬取数据的时候,数据量比较大,单个爬虫的爬取速度太慢。使用爬虫时,需要多个爬虫进行爬取。这时候就需要使用IP代理,使用多个动态IP进行爬取。抓取可以提高爬虫效率,同时降低单个IP访问频率,降低风险。
  
  那么爬虫是如何抓取大量IP的呢?比如对于数据采集,我们使用分布式网络爬虫,使用多台服务器,多个IP,多个slave网络爬虫同时运行,master负责调度。效率更高,属于大规模分布式爬取。一般使用Redis分布式爬取。
  那么这个IP是怎么来的呢?IP地址仍然缺乏,我们仍然使用动态IP地址,那么如何更改IP地址?爬虫使用的IP地址可不是那么简单的几个。它们需要轮流使用。抓取的网页越多,需要的 IP 就越多。否则同一个IP访问次数过多。即使访问频率不快,仍然会引起网站的关注,限制访问。
  获取IP地址的方法有:
  根据ADSL拨号服务器修改IP。每次拨号都会有一个新的IP,更好的解决了IP单一的问题。
  如果是带路由器的局域网,第一种方法可能效果不好。这时候可以模拟登录路由器,控制路由器重拨,修改IP。这其实是一种折衷的方法,曲线救国。
  代理IP,使用网上购买或爬取的免费代理IP,实现多IP网络爬取。
  不过免费代理IP的效果不是很好。你可以自己做,所以我不会在这里谈论它。为了爬取的效率,小编还是推荐购买代理IP,比如IP精灵的动态拨号vps。综上所述,爬虫可以抓取多个IP,获取IP的方式有多种。至于选择哪种方式,要看你需要的IP数量和IP的质量。 查看全部

  java爬虫抓取动态网页(爬虫多IP抓取怎么获取大量IP?方法有哪些?)
  网络爬虫如何获取大量动态IP进行数据抓取?通常在爬取数据的时候,数据量比较大,单个爬虫的爬取速度太慢。使用爬虫时,需要多个爬虫进行爬取。这时候就需要使用IP代理,使用多个动态IP进行爬取。抓取可以提高爬虫效率,同时降低单个IP访问频率,降低风险。
  
  那么爬虫是如何抓取大量IP的呢?比如对于数据采集,我们使用分布式网络爬虫,使用多台服务器,多个IP,多个slave网络爬虫同时运行,master负责调度。效率更高,属于大规模分布式爬取。一般使用Redis分布式爬取。
  那么这个IP是怎么来的呢?IP地址仍然缺乏,我们仍然使用动态IP地址,那么如何更改IP地址?爬虫使用的IP地址可不是那么简单的几个。它们需要轮流使用。抓取的网页越多,需要的 IP 就越多。否则同一个IP访问次数过多。即使访问频率不快,仍然会引起网站的关注,限制访问。
  获取IP地址的方法有:
  根据ADSL拨号服务器修改IP。每次拨号都会有一个新的IP,更好的解决了IP单一的问题。
  如果是带路由器的局域网,第一种方法可能效果不好。这时候可以模拟登录路由器,控制路由器重拨,修改IP。这其实是一种折衷的方法,曲线救国。
  代理IP,使用网上购买或爬取的免费代理IP,实现多IP网络爬取。
  不过免费代理IP的效果不是很好。你可以自己做,所以我不会在这里谈论它。为了爬取的效率,小编还是推荐购买代理IP,比如IP精灵的动态拨号vps。综上所述,爬虫可以抓取多个IP,获取IP的方式有多种。至于选择哪种方式,要看你需要的IP数量和IP的质量。

java爬虫抓取动态网页(爬虫科普一下对爬虫的误区、原理以及实现(组图))

网站优化优采云 发表了文章 • 0 个评论 • 62 次浏览 • 2021-12-06 11:03 • 来自相关话题

  java爬虫抓取动态网页(爬虫科普一下对爬虫的误区、原理以及实现(组图))
  爬虫?相信很多人都熟悉这个词。简单的说就是利用工具对网页上的数据进行爬取,并进行排序和分析。照例告诉小白爬虫的误区、原理和实现。
  爬虫常见误区:python=爬虫?
  很多新手都会把python等同于爬虫。其实python是一种计算机编程语言。它不仅可以做爬虫,还可以构建Web应用程序。最近很火的人工智能也可以用python语言来实现。的。
  爬虫的本质是抓取服务器响应浏览器的数据(原理会在下面详述)。Java、C#等不同的计算机编程语言都可以实现爬虫。
  总结:python≠爬虫,python的功能远比我们想象的要强大,爬虫不仅仅只有python才有可能。
  履带原理
  让我们回忆一下我们访问百度时的过程:
  1.在地址栏中输入网址:
  肯定有人会说我以前从来没有这样做过。我一直都是用浏览器打开导航进入百度。
  其实这种方式进入百度,只不过是浏览器为你输入了访问百度的链接。
  2. 浏览器刷新了,百度的搜索框出现在我们面前。
  当然网速不能刷新的情况就不考虑了。
  在此期间,浏览器和服务器之间发生了什么?
  1. 浏览器向服务器发送URL,即请求的地址。
  2. 服务器收到浏览器的网络请求,开始向浏览器响应数据。
  3. 浏览器接收服务器发送来的数据,进行分析,显示出来。
  有兴趣的可以清除浏览器缓存,使用Fn+F12组合键打开浏览器控制台,选择NetWork菜单,可以看到页面刷新时的具体响应过程
  爬虫的实现机制
  1.既然浏览器可以将请求地址发送到服务器,我们也可以通过程序向服务器发起请求。
  2.既然浏览器可以接收到服务器发来的数据,我们就可以模仿浏览器的解析过程,过滤得到我们想要的数据。
  总结:通过我们自己的程序,不需要反复组织我们想要的数据。所有这些都是由我们的爬虫程序完成的。
  Java爬虫的具体案例
  目标:抓取动态模块显示的最新新闻,并将新闻内容以文件形式保存在本地。
  
  爬取资源 1
  
  爬取资源2
  (一) 需求分析
  1.新闻网首页解析,抓取部门动态模块内容
  2.模拟跳转,进入各个新闻页面,抓取新闻的具体内容
  3.将新闻的具体内容保存在一个文件中
  (二)代码实现
  1.使用maven工具,在pom.xml中导入我们爬虫依赖的jar包
  


org.apache.httpcomponents
httpclient
4.5.3



org.jsoup
jsoup
1.8.3



log4j
log4j
1.2.16



junit
junit
4.10


  2. 做一个发送请求的简单类
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
public class MyClient {
public String getContent(String url) throws ClientProtocolException, IOException {
// 创建httpclient对象
HttpClient hClient = new DefaultHttpClient();
// 设置连接超时时间,响应超时时间,以及代理服务器
hClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000)
.setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
.setParameter(ConnRouteParams.DEFAULT_PROXY, new HttpHost("117.191.11.71", 8080));
// 创建get请求对象
HttpGet hGet = new HttpGet(url);
// 模拟请求,获得服务器响应的源码
HttpResponse response = hClient.execute(hGet);
// 将源码转换为字符串
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
// 返回转化后的字符串
return content;
}
}
  3. 做一个解析服务器数据的类
  package com.sxau.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class MyJsoup {
public Elements getTarget(
String htmlResource,String selectCondition) {
//解析服务器发来的数据
Document doc = Jsoup.parse(htmlResource);
//对解析后的数据通过条件筛选
Elements elements = doc.select(selectCondition);
return elements;
}
}
  4. 制作一个类在本地存储文件
  package com.sxau.example;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class MyFileIO {
public void makeFile(String title,String txtContent) throws IOException {
//将标题左右多余的空格去掉
title = title.trim();
//拿到当前应用所在路径
String property = System.getProperty("user.dir");
//设置生成文件的路径与名称
String filePath = property + "\\src\\main\\webapp\\spidertxt\\" + title + ".txt";
//生成新文件
File txt = new File(filePath);
//将文件输入器定位到刚刚生成的新文件
FileWriter writer = new FileWriter(txt);
//将已经匹配的字符串写入文件中
writer.write(txtContent);
//刷新并关闭流
writer.flush();
writer.close();
}
}
  5. 为了提高效率,创建线程并发处理
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.select.Elements;
/**
* 实现Runable接口
* @author Administrator
*
*/
public class MyThread implements Runnable{

private String mainUrl;
private String singleUrl;
//提供有参数的构造方法,确保进入页面时url不为空
public MyThread(String mainUrl, String singleUrl) {
this.mainUrl = mainUrl;
this.singleUrl = singleUrl;
}
/**
* 实现接口未实现的run()方法
* 通过httpclient发送请求并接收数据
* 观察html页面,使用jsoup中便捷的仿css/js选择器语法得到我们需要的内容
* 对匹配好的字符串进行优化,并进行本地存储
*/
@Override
public void run() {
// TODO 自动生成的方法存根
MyClient myClient = new MyClient();
String url=mainUrl+singleUrl;
String content;
try {
content = myClient.getContent(url);
String selectCondition1=".arti_title";
String selectCondition2=".wp_articlecontent";
MyJsoup jsoup = new MyJsoup();
Elements elements1 = jsoup.getTarget(content, selectCondition1);
Elements elements2 = jsoup.getTarget(content, selectCondition2);
String html1 = elements1.get(0).html();
String title = html1.replaceAll("", "");
String html2 = elements2.get(0).html();
html2 = html2.replaceAll("<p>", "");
String word = html2.replaceAll("", "");
MyFileIO fileIO=new MyFileIO();
fileIO.makeFile(title, word);
} catch (ClientProtocolException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

}

}
</p>
  6.制作主程序
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class MySpider {
public static void main(String[] args) throws ClientProtocolException, IOException {
MyClient myClient = new MyClient();
String url="http://news.sxau.edu.cn/";
String content = myClient.getContent(url);
String selectCondition="a[href][title~=(|)]";
MyJsoup jsoup = new MyJsoup();
Elements elements = jsoup.getTarget(content, selectCondition);
for (Element element : elements) {
String attr = element.attr("href");
new Thread(new MyThread(url, attr)).start();
}
System.out.println("文件爬虫成功!");
}
}
  6.运行mian方法,稍等片刻,刚出炉的文件已经静静的躺在文件夹里了。
  log4j:WARN No appenders could be found for logger (org.apache.http.impl.conn.BasicClientConnectionManager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4 ... onfig for more info.
文件爬虫成功!
  
  最终效果
  至此,一个简单的爬虫功能已经实现。菜鸟们,有什么问题,欢迎大家赐教,互相探讨,共同进步。 查看全部

  java爬虫抓取动态网页(爬虫科普一下对爬虫的误区、原理以及实现(组图))
  爬虫?相信很多人都熟悉这个词。简单的说就是利用工具对网页上的数据进行爬取,并进行排序和分析。照例告诉小白爬虫的误区、原理和实现。
  爬虫常见误区:python=爬虫?
  很多新手都会把python等同于爬虫。其实python是一种计算机编程语言。它不仅可以做爬虫,还可以构建Web应用程序。最近很火的人工智能也可以用python语言来实现。的。
  爬虫的本质是抓取服务器响应浏览器的数据(原理会在下面详述)。Java、C#等不同的计算机编程语言都可以实现爬虫。
  总结:python≠爬虫,python的功能远比我们想象的要强大,爬虫不仅仅只有python才有可能。
  履带原理
  让我们回忆一下我们访问百度时的过程:
  1.在地址栏中输入网址:
  肯定有人会说我以前从来没有这样做过。我一直都是用浏览器打开导航进入百度。
  其实这种方式进入百度,只不过是浏览器为你输入了访问百度的链接。
  2. 浏览器刷新了,百度的搜索框出现在我们面前。
  当然网速不能刷新的情况就不考虑了。
  在此期间,浏览器和服务器之间发生了什么?
  1. 浏览器向服务器发送URL,即请求的地址。
  2. 服务器收到浏览器的网络请求,开始向浏览器响应数据。
  3. 浏览器接收服务器发送来的数据,进行分析,显示出来。
  有兴趣的可以清除浏览器缓存,使用Fn+F12组合键打开浏览器控制台,选择NetWork菜单,可以看到页面刷新时的具体响应过程
  爬虫的实现机制
  1.既然浏览器可以将请求地址发送到服务器,我们也可以通过程序向服务器发起请求。
  2.既然浏览器可以接收到服务器发来的数据,我们就可以模仿浏览器的解析过程,过滤得到我们想要的数据。
  总结:通过我们自己的程序,不需要反复组织我们想要的数据。所有这些都是由我们的爬虫程序完成的。
  Java爬虫的具体案例
  目标:抓取动态模块显示的最新新闻,并将新闻内容以文件形式保存在本地。
  
  爬取资源 1
  
  爬取资源2
  (一) 需求分析
  1.新闻网首页解析,抓取部门动态模块内容
  2.模拟跳转,进入各个新闻页面,抓取新闻的具体内容
  3.将新闻的具体内容保存在一个文件中
  (二)代码实现
  1.使用maven工具,在pom.xml中导入我们爬虫依赖的jar包
  


org.apache.httpcomponents
httpclient
4.5.3



org.jsoup
jsoup
1.8.3



log4j
log4j
1.2.16



junit
junit
4.10


  2. 做一个发送请求的简单类
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
public class MyClient {
public String getContent(String url) throws ClientProtocolException, IOException {
// 创建httpclient对象
HttpClient hClient = new DefaultHttpClient();
// 设置连接超时时间,响应超时时间,以及代理服务器
hClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000)
.setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
.setParameter(ConnRouteParams.DEFAULT_PROXY, new HttpHost("117.191.11.71", 8080));
// 创建get请求对象
HttpGet hGet = new HttpGet(url);
// 模拟请求,获得服务器响应的源码
HttpResponse response = hClient.execute(hGet);
// 将源码转换为字符串
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
// 返回转化后的字符串
return content;
}
}
  3. 做一个解析服务器数据的类
  package com.sxau.example;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class MyJsoup {
public Elements getTarget(
String htmlResource,String selectCondition) {
//解析服务器发来的数据
Document doc = Jsoup.parse(htmlResource);
//对解析后的数据通过条件筛选
Elements elements = doc.select(selectCondition);
return elements;
}
}
  4. 制作一个类在本地存储文件
  package com.sxau.example;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class MyFileIO {
public void makeFile(String title,String txtContent) throws IOException {
//将标题左右多余的空格去掉
title = title.trim();
//拿到当前应用所在路径
String property = System.getProperty("user.dir");
//设置生成文件的路径与名称
String filePath = property + "\\src\\main\\webapp\\spidertxt\\" + title + ".txt";
//生成新文件
File txt = new File(filePath);
//将文件输入器定位到刚刚生成的新文件
FileWriter writer = new FileWriter(txt);
//将已经匹配的字符串写入文件中
writer.write(txtContent);
//刷新并关闭流
writer.flush();
writer.close();
}
}
  5. 为了提高效率,创建线程并发处理
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.select.Elements;
/**
* 实现Runable接口
* @author Administrator
*
*/
public class MyThread implements Runnable{

private String mainUrl;
private String singleUrl;
//提供有参数的构造方法,确保进入页面时url不为空
public MyThread(String mainUrl, String singleUrl) {
this.mainUrl = mainUrl;
this.singleUrl = singleUrl;
}
/**
* 实现接口未实现的run()方法
* 通过httpclient发送请求并接收数据
* 观察html页面,使用jsoup中便捷的仿css/js选择器语法得到我们需要的内容
* 对匹配好的字符串进行优化,并进行本地存储
*/
@Override
public void run() {
// TODO 自动生成的方法存根
MyClient myClient = new MyClient();
String url=mainUrl+singleUrl;
String content;
try {
content = myClient.getContent(url);
String selectCondition1=".arti_title";
String selectCondition2=".wp_articlecontent";
MyJsoup jsoup = new MyJsoup();
Elements elements1 = jsoup.getTarget(content, selectCondition1);
Elements elements2 = jsoup.getTarget(content, selectCondition2);
String html1 = elements1.get(0).html();
String title = html1.replaceAll("", "");
String html2 = elements2.get(0).html();
html2 = html2.replaceAll("<p>", "");
String word = html2.replaceAll("", "");
MyFileIO fileIO=new MyFileIO();
fileIO.makeFile(title, word);
} catch (ClientProtocolException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

}

}
</p>
  6.制作主程序
  package com.sxau.example;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class MySpider {
public static void main(String[] args) throws ClientProtocolException, IOException {
MyClient myClient = new MyClient();
String url="http://news.sxau.edu.cn/";
String content = myClient.getContent(url);
String selectCondition="a[href][title~=(|)]";
MyJsoup jsoup = new MyJsoup();
Elements elements = jsoup.getTarget(content, selectCondition);
for (Element element : elements) {
String attr = element.attr("href");
new Thread(new MyThread(url, attr)).start();
}
System.out.println("文件爬虫成功!");
}
}
  6.运行mian方法,稍等片刻,刚出炉的文件已经静静的躺在文件夹里了。
  log4j:WARN No appenders could be found for logger (org.apache.http.impl.conn.BasicClientConnectionManager).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4 ... onfig for more info.
文件爬虫成功!
  
  最终效果
  至此,一个简单的爬虫功能已经实现。菜鸟们,有什么问题,欢迎大家赐教,互相探讨,共同进步。

java爬虫抓取动态网页(java爬虫抓取动态网页的内容,不是专业的不懂)

网站优化优采云 发表了文章 • 0 个评论 • 37 次浏览 • 2021-12-03 20:12 • 来自相关话题

  java爬虫抓取动态网页(java爬虫抓取动态网页的内容,不是专业的不懂)
  java爬虫抓取动态网页的内容,不是java专业的不懂,但我能给的建议是换html页面,markdown语言解析html文本,然后对其进行解析抓取。其实也可以考虑一下python,它抓取和解析html的能力都不错。
  我个人更倾向于go,为啥不选一个爬虫程序作为主力来爬虫?自己学程序解析html,js解析等等,
  先全换成c#,再半伪代码半java,最后全换成pythonjava等动态语言。要解决的问题要有先后顺序。我没见过爬虫程序从全伪代码半java改成从只有java到解析html等动态语言的,
  可以看一下我的golang学习总结系列文章golang快速入门总结:上一篇:golang快速入门总结:数据分析、机器学习、爬虫系列文章;下一篇:golang快速入门总结:动态网页爬取系列文章;
  我没有经历过爬虫的全过程,只能给出一些有针对性的方法。你的开发环境是怎么样的,可以统一安装一些爬虫环境。第一步,把你手头已有的网站爬下来,然后封装成api。但你做过网站的代码审查。怎么让你需要的网站用go开发都给你封装好。第二步,封装好api之后,可以把url里面的参数,将这些参数封装成一个或多个类方法,每个方法里面封装对应的参数(单个参数是无法通过api获取)。
  这样就实现了python爬虫的后面两步。同时,用java来写代码就很容易。你需要从头写起。如果你以前没有做过爬虫,那么需要补一下java相关的基础知识。 查看全部

  java爬虫抓取动态网页(java爬虫抓取动态网页的内容,不是专业的不懂)
  java爬虫抓取动态网页的内容,不是java专业的不懂,但我能给的建议是换html页面,markdown语言解析html文本,然后对其进行解析抓取。其实也可以考虑一下python,它抓取和解析html的能力都不错。
  我个人更倾向于go,为啥不选一个爬虫程序作为主力来爬虫?自己学程序解析html,js解析等等,
  先全换成c#,再半伪代码半java,最后全换成pythonjava等动态语言。要解决的问题要有先后顺序。我没见过爬虫程序从全伪代码半java改成从只有java到解析html等动态语言的,
  可以看一下我的golang学习总结系列文章golang快速入门总结:上一篇:golang快速入门总结:数据分析、机器学习、爬虫系列文章;下一篇:golang快速入门总结:动态网页爬取系列文章;
  我没有经历过爬虫的全过程,只能给出一些有针对性的方法。你的开发环境是怎么样的,可以统一安装一些爬虫环境。第一步,把你手头已有的网站爬下来,然后封装成api。但你做过网站的代码审查。怎么让你需要的网站用go开发都给你封装好。第二步,封装好api之后,可以把url里面的参数,将这些参数封装成一个或多个类方法,每个方法里面封装对应的参数(单个参数是无法通过api获取)。
  这样就实现了python爬虫的后面两步。同时,用java来写代码就很容易。你需要从头写起。如果你以前没有做过爬虫,那么需要补一下java相关的基础知识。

java爬虫抓取动态网页(实战|手把手教你用Python爬虫(附详细源码)(图))

网站优化优采云 发表了文章 • 0 个评论 • 49 次浏览 • 2021-12-01 18:10 • 来自相关话题

  java爬虫抓取动态网页(实战|手把手教你用Python爬虫(附详细源码)(图))
  项目背景
  事情是这样的。前几天,我的公众号写了一篇实战爬虫入口文章,名为《实战|教你使用Python爬虫(附详细源码)》。发出后不到一天,一位从业10年的王律师找上我。虽然同意了他的微信申请,但心里还是有些慌。
  点击此处获取海量Python学习资料!
  
  短暂交流后,原来他是在自学爬虫,结果翻页发现网址没变。其实他爬取的网页难度比较大,也就是这次要详细介绍的动态网页。一向乐于助人的J哥,自然会在最短的时间内给他指明方向,从青铜到白银。
  AJAX 动态加载网页
  一
  什么是动态网页
  J哥一向注重理论与实践的结合,知其然也必知其所以然,才能应付一切变化而无变化。
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。——来源百度百科
  动态网页具有工作量少、内容更新快、功能更齐全的特点。被很多公司采用,如购动、速食宝、速食等。
  二
  什么是 AJAX
  随着人们对动态网页的加载速度要求越来越高,AJAX 技术应运而生,成为许多网站的首选。AJAX 是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,使网页可以异步更新。这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。
  三
  如何抓取AJAX动态加载的网页
  1. 分析界面
  只要有数据发送,就一定有请求发送到服务器。我们只需要找出它静默加载的页面的真实请求。特点:爬取速度快,爬取数据干净,部分网站比较难解析。
  2. 硒
  什么是硒?它最初是一个自动化测试工具,但它被广泛的用户抓取。是一个可以用代码操作浏览器的工具,比如控制浏览器的下滑,模拟鼠标点击等。 特点:代码比较简单,爬取速度慢,IP容易被封。
  项目实践
  理论这么多,老实说,J哥也不想这么啰嗦。但是,这些东西经常被问到,所以把它们写下来。下次有人问,就送他这个文章,一劳永逸!
  
  好,让我们回到王律师的部分。作为资深律师,王律师深知,研究法院多年来公开的开庭信息和执行信息,对于提升业务能力具有重要作用。于是他兴高采烈地打开了法庭信息公开网页。
  它看起来像这样:
  
  然后,他按照J哥之前写的爬虫介绍文章抓取数据,成功提取到第一页。他异常兴奋。
  
  紧接着,他又加了一个for循环,想着花几分钟把这个网站2164页共32457条宣判数据提取到excel中。
  然后,就没有了。你也应该知道,看了前面的理论部分,这是一个AJAX动态加载的网页。无论你如何点击下一页,url都不会改变。如果你不相信我,我就给你看。左上角的url像山一样矗立在那里:
  
  一
  解析接口
  既然如此,那我们就开始爬虫的正确姿势,先用解析接口的方法来写爬虫。
  首先,找到真正的请求。右键勾选,点击Network,选择XHR,刷新网页,在Name列表中选择jsp文件。没错,就是这么简单,真正的要求就藏在里面。
  
  再仔细看看这个jsp,这简直就是宝藏。有真实的请求url、post请求方法、Headers、Form Data,From Data代表传递给url的参数。通过改变参数,我们可以得到数据!为了安全起见,我为我的 Cookie 做了马赛克。机智的朋友可能已经发现我顺便给自己打了广告。
  
  让我们仔细看看这些参数, pagesnum 参数不仅仅代表页数!王律师顿时恍然大悟,原来他思考的那一页,竟然翻到了这里!穿越千山万水,终于找到了你!我们尝试点击翻页,发现只有 pagesnum 参数会发生变化。
  
  既然找到了,赶紧抓起来吧。J哥以闪电般的速度打开了PyCharm,导入了爬虫需要的库。
  1from urllib.parse import urlencode
2import csv
3import random
4import requests
5import traceback
6from time import sleep
7from lxml import etree #lxml为第三方网页解析库,强大且速度快
  构造一个真正的请求并添加标题。J哥没有把他的User-Agent和Cookie贴在这里,主要是一向胆小的J哥被吓到了。
   1base_url = &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B #这里要换成对应Ajax请求中的链接
2
3headers = {
4 &#39;Connection&#39;: &#39;keep-alive&#39;,
5 &#39;Accept&#39;: &#39;*/*&#39;,
6 &#39;X-Requested-With&#39;: &#39;XMLHttpRequest&#39;,
7 &#39;User-Agent&#39;: &#39;你的User-Agent&#39;,
8 &#39;Origin&#39;: &#39;http://www.hshfy.sh.cn&#39;,
9 &#39;Referer&#39;: &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B,
10 &#39;Accept-Language&#39;: &#39;zh-CN,zh;q=0.9&#39;,
11 &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;,
12 &#39;Cookie&#39;: &#39;你的Cookie&#39;
13}
  构造get_page函数,参数为page,即页数。创建字典类型的表单数据,并使用post请求网页数据。这里一定要注意对返回数据的解码,编码为'gbk',否则返回数据会出现乱码!另外,我还优化了异常处理,防止意外。
   1def get_page(page):
2 n = 3
3 while True:
4 try:
5 sleep(random.uniform(1, 2)) # 随机出现1-2之间的数,包含小数
6 data = {
7 &#39;yzm&#39;: &#39;yxAH&#39;,
8 &#39;ft&#39;:&#39;&#39;,
9 &#39;ktrqks&#39;: &#39;2020-05-22&#39;,
10 &#39;ktrqjs&#39;: &#39;2020-06-22&#39;,
11 &#39;spc&#39;:&#39;&#39;,
12 &#39;yg&#39;:&#39;&#39;,
13 &#39;bg&#39;:&#39;&#39;,
14 &#39;ah&#39;:&#39;&#39;,
15 &#39;pagesnum&#39;: page
16 }
17 url = base_url + urlencode(data)
18 print(url)
19 try:
20 response = requests.request("POST",url, headers = headers)
21 #print(response)
22 if response.status_code == 200:
23 re = response.content.decode(&#39;gbk&#39;)
24 # print(re)
25 return re # 解析内容
26 except requests.ConnectionError as e:
27 print(&#39;Error&#39;, e.args) # 输出异常信息
28 except (TimeoutError, Exception):
29 n -= 1
30 if n == 0:
31 print(&#39;请求3次均失败,放弃此url请求,检查请求条件&#39;)
32 return
33 else:
34 print(&#39;请求失败,重新请求&#39;)
35 continue
  构造parse_page函数解析返回的网页数据,用Xpath提取所有字段内容,并保存为csv格式。有人会问为什么J哥那么喜欢用Xpath,因为它简单好用!!!这么简单的网页结构,我做不了普通的大法安装。J兄弟,我做不到。
   1def parse_page(html):
2 try:
3 parse = etree.HTML(html) # 解析网页
4 items = parse.xpath(&#39;//*[@id="report"]/tbody/tr&#39;)
5 for item in items[1:]:
6 item = {
7 &#39;a&#39;: &#39;&#39;.join(item.xpath(&#39;./td[1]/font/text()&#39;)).strip(),
8 &#39;b&#39;: &#39;&#39;.join(item.xpath(&#39;./td[2]/font/text()&#39;)).strip(),
9 &#39;c&#39;: &#39;&#39;.join(item.xpath(&#39;./td[3]/text()&#39;)).strip(),
10 &#39;d&#39;: &#39;&#39;.join(item.xpath(&#39;./td[4]/text()&#39;)).strip(),
11 &#39;e&#39;: &#39;&#39;.join(item.xpath(&#39;./td[5]/text()&#39;)).strip(),
12 &#39;f&#39;: &#39;&#39;.join(item.xpath(&#39;./td[6]/div/text()&#39;)).strip(),
13 &#39;g&#39;: &#39;&#39;.join(item.xpath(&#39;./td[7]/div/text()&#39;)).strip(),
14 &#39;h&#39;: &#39;&#39;.join(item.xpath(&#39;./td[8]/text()&#39;)).strip(),
15 &#39;i&#39;: &#39;&#39;.join(item.xpath(&#39;./td[9]/text()&#39;)).strip()
16 }
17 #print(item)
18 try:
19 with open(&#39;./law.csv&#39;, &#39;a&#39;, encoding=&#39;utf_8_sig&#39;, newline=&#39;&#39;) as fp:
20 # &#39;a&#39;为追加模式(添加)
21 # utf_8_sig格式导出csv不乱码
22 fieldnames = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;,&#39;f&#39;,&#39;g&#39;,&#39;h&#39;,&#39;i&#39;]
23 writer = csv.DictWriter(fp,fieldnames)
24 writer.writerow(item)
25 except Exception:
26 print(traceback.print_exc()) #代替print e 来输出详细的异常信息
27 except Exception:
28 print(traceback.print_exc())
  最后遍历页数,调用函数。OK完成!
  1 for page in range(1,5): #这里设置想要爬取的页数
2 html = get_page(page)
3 #print(html)
4 print("第" + str(page) + "页提取完成")
  我们来看看最终的效果:
  
  二
  硒
  渴望学习的朋友可能还想看看Selenium是如何爬取AJAX动态加载的网页的。J哥自然会满足你的好奇心。于是赶紧新建了一个py文件,准备趁势而上,用Selenium把这个网站爬下来。
  首先,导入相关库。
  1from lxml import etree
2import time
3from selenium import webdriver
4from selenium. webdriver.support.wait import WebDriverWait
5from selenium.webdriver.support import expected_conditions as EC
6from selenium.webdriver.common.by import By
  然后,使用chromedriver驱动打开这个网站。
  1def main():
2 # 爬取首页url
3 url = "http://www.hshfy.sh.cn/shfy/gw ... ot%3B
4 # 定义谷歌webdriver
5 driver = webdriver.Chrome(&#39;./chromedriver&#39;)
6 driver.maximize_window() # 将浏览器最大化
7 driver.get(url)
  所以,我惊讶地发现报告了一个错误。以CET-6英语的词汇储备,J哥居然听懂了!可能是我的驱动和浏览器版本不匹配,只支持79版本的浏览器。
  J兄很郁闷,因为我以前用Selenium从来没有遇到过这种问题。J哥不甘心,打开谷歌浏览器查看版本号。
  
  我失去了它!都更新到了81版!遇到这种情况,请好奇的朋友等待J哥设置浏览器自动更新并重新下载最新驱动,下次再来听听Selenium爬虫吧。记得关注本公众号,不要错过精彩哦~
  综上所述,对于网络爬虫的AJAX动态加载,一般有两种方式:解析接口;硒。J兄推荐解析接口的方式。如果是解析json数据,最好是爬取。如果你不知道如何使用Selenium,让我们使用Selenium。 查看全部

  java爬虫抓取动态网页(实战|手把手教你用Python爬虫(附详细源码)(图))
  项目背景
  事情是这样的。前几天,我的公众号写了一篇实战爬虫入口文章,名为《实战|教你使用Python爬虫(附详细源码)》。发出后不到一天,一位从业10年的王律师找上我。虽然同意了他的微信申请,但心里还是有些慌。
  点击此处获取海量Python学习资料!
  
  短暂交流后,原来他是在自学爬虫,结果翻页发现网址没变。其实他爬取的网页难度比较大,也就是这次要详细介绍的动态网页。一向乐于助人的J哥,自然会在最短的时间内给他指明方向,从青铜到白银。
  AJAX 动态加载网页
  一
  什么是动态网页
  J哥一向注重理论与实践的结合,知其然也必知其所以然,才能应付一切变化而无变化。
  所谓动态网页,是指一种与静态网页相对的网页编程技术。对于静态网页,随着html代码的生成,页面的内容和显示效果基本不会发生变化——除非你修改页面代码。这不是动态网页的情况。虽然页面代码没有改变,但显示的内容会随着时间、环境或数据库操作的结果而改变。——来源百度百科
  动态网页具有工作量少、内容更新快、功能更齐全的特点。被很多公司采用,如购动、速食宝、速食等。
  二
  什么是 AJAX
  随着人们对动态网页的加载速度要求越来越高,AJAX 技术应运而生,成为许多网站的首选。AJAX 是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,使网页可以异步更新。这意味着可以在不重新加载整个网页的情况下更新网页的某些部分。
  三
  如何抓取AJAX动态加载的网页
  1. 分析界面
  只要有数据发送,就一定有请求发送到服务器。我们只需要找出它静默加载的页面的真实请求。特点:爬取速度快,爬取数据干净,部分网站比较难解析。
  2. 硒
  什么是硒?它最初是一个自动化测试工具,但它被广泛的用户抓取。是一个可以用代码操作浏览器的工具,比如控制浏览器的下滑,模拟鼠标点击等。 特点:代码比较简单,爬取速度慢,IP容易被封。
  项目实践
  理论这么多,老实说,J哥也不想这么啰嗦。但是,这些东西经常被问到,所以把它们写下来。下次有人问,就送他这个文章,一劳永逸!
  
  好,让我们回到王律师的部分。作为资深律师,王律师深知,研究法院多年来公开的开庭信息和执行信息,对于提升业务能力具有重要作用。于是他兴高采烈地打开了法庭信息公开网页。
  它看起来像这样:
  
  然后,他按照J哥之前写的爬虫介绍文章抓取数据,成功提取到第一页。他异常兴奋。
  
  紧接着,他又加了一个for循环,想着花几分钟把这个网站2164页共32457条宣判数据提取到excel中。
  然后,就没有了。你也应该知道,看了前面的理论部分,这是一个AJAX动态加载的网页。无论你如何点击下一页,url都不会改变。如果你不相信我,我就给你看。左上角的url像山一样矗立在那里:
  
  一
  解析接口
  既然如此,那我们就开始爬虫的正确姿势,先用解析接口的方法来写爬虫。
  首先,找到真正的请求。右键勾选,点击Network,选择XHR,刷新网页,在Name列表中选择jsp文件。没错,就是这么简单,真正的要求就藏在里面。
  
  再仔细看看这个jsp,这简直就是宝藏。有真实的请求url、post请求方法、Headers、Form Data,From Data代表传递给url的参数。通过改变参数,我们可以得到数据!为了安全起见,我为我的 Cookie 做了马赛克。机智的朋友可能已经发现我顺便给自己打了广告。
  
  让我们仔细看看这些参数, pagesnum 参数不仅仅代表页数!王律师顿时恍然大悟,原来他思考的那一页,竟然翻到了这里!穿越千山万水,终于找到了你!我们尝试点击翻页,发现只有 pagesnum 参数会发生变化。
  
  既然找到了,赶紧抓起来吧。J哥以闪电般的速度打开了PyCharm,导入了爬虫需要的库。
  1from urllib.parse import urlencode
2import csv
3import random
4import requests
5import traceback
6from time import sleep
7from lxml import etree #lxml为第三方网页解析库,强大且速度快
  构造一个真正的请求并添加标题。J哥没有把他的User-Agent和Cookie贴在这里,主要是一向胆小的J哥被吓到了。
   1base_url = &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B #这里要换成对应Ajax请求中的链接
2
3headers = {
4 &#39;Connection&#39;: &#39;keep-alive&#39;,
5 &#39;Accept&#39;: &#39;*/*&#39;,
6 &#39;X-Requested-With&#39;: &#39;XMLHttpRequest&#39;,
7 &#39;User-Agent&#39;: &#39;你的User-Agent&#39;,
8 &#39;Origin&#39;: &#39;http://www.hshfy.sh.cn&#39;,
9 &#39;Referer&#39;: &#39;http://www.hshfy.sh.cn/shfy/gw ... 39%3B,
10 &#39;Accept-Language&#39;: &#39;zh-CN,zh;q=0.9&#39;,
11 &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;,
12 &#39;Cookie&#39;: &#39;你的Cookie&#39;
13}
  构造get_page函数,参数为page,即页数。创建字典类型的表单数据,并使用post请求网页数据。这里一定要注意对返回数据的解码,编码为'gbk',否则返回数据会出现乱码!另外,我还优化了异常处理,防止意外。
   1def get_page(page):
2 n = 3
3 while True:
4 try:
5 sleep(random.uniform(1, 2)) # 随机出现1-2之间的数,包含小数
6 data = {
7 &#39;yzm&#39;: &#39;yxAH&#39;,
8 &#39;ft&#39;:&#39;&#39;,
9 &#39;ktrqks&#39;: &#39;2020-05-22&#39;,
10 &#39;ktrqjs&#39;: &#39;2020-06-22&#39;,
11 &#39;spc&#39;:&#39;&#39;,
12 &#39;yg&#39;:&#39;&#39;,
13 &#39;bg&#39;:&#39;&#39;,
14 &#39;ah&#39;:&#39;&#39;,
15 &#39;pagesnum&#39;: page
16 }
17 url = base_url + urlencode(data)
18 print(url)
19 try:
20 response = requests.request("POST",url, headers = headers)
21 #print(response)
22 if response.status_code == 200:
23 re = response.content.decode(&#39;gbk&#39;)
24 # print(re)
25 return re # 解析内容
26 except requests.ConnectionError as e:
27 print(&#39;Error&#39;, e.args) # 输出异常信息
28 except (TimeoutError, Exception):
29 n -= 1
30 if n == 0:
31 print(&#39;请求3次均失败,放弃此url请求,检查请求条件&#39;)
32 return
33 else:
34 print(&#39;请求失败,重新请求&#39;)
35 continue
  构造parse_page函数解析返回的网页数据,用Xpath提取所有字段内容,并保存为csv格式。有人会问为什么J哥那么喜欢用Xpath,因为它简单好用!!!这么简单的网页结构,我做不了普通的大法安装。J兄弟,我做不到。
   1def parse_page(html):
2 try:
3 parse = etree.HTML(html) # 解析网页
4 items = parse.xpath(&#39;//*[@id="report"]/tbody/tr&#39;)
5 for item in items[1:]:
6 item = {
7 &#39;a&#39;: &#39;&#39;.join(item.xpath(&#39;./td[1]/font/text()&#39;)).strip(),
8 &#39;b&#39;: &#39;&#39;.join(item.xpath(&#39;./td[2]/font/text()&#39;)).strip(),
9 &#39;c&#39;: &#39;&#39;.join(item.xpath(&#39;./td[3]/text()&#39;)).strip(),
10 &#39;d&#39;: &#39;&#39;.join(item.xpath(&#39;./td[4]/text()&#39;)).strip(),
11 &#39;e&#39;: &#39;&#39;.join(item.xpath(&#39;./td[5]/text()&#39;)).strip(),
12 &#39;f&#39;: &#39;&#39;.join(item.xpath(&#39;./td[6]/div/text()&#39;)).strip(),
13 &#39;g&#39;: &#39;&#39;.join(item.xpath(&#39;./td[7]/div/text()&#39;)).strip(),
14 &#39;h&#39;: &#39;&#39;.join(item.xpath(&#39;./td[8]/text()&#39;)).strip(),
15 &#39;i&#39;: &#39;&#39;.join(item.xpath(&#39;./td[9]/text()&#39;)).strip()
16 }
17 #print(item)
18 try:
19 with open(&#39;./law.csv&#39;, &#39;a&#39;, encoding=&#39;utf_8_sig&#39;, newline=&#39;&#39;) as fp:
20 # &#39;a&#39;为追加模式(添加)
21 # utf_8_sig格式导出csv不乱码
22 fieldnames = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;,&#39;f&#39;,&#39;g&#39;,&#39;h&#39;,&#39;i&#39;]
23 writer = csv.DictWriter(fp,fieldnames)
24 writer.writerow(item)
25 except Exception:
26 print(traceback.print_exc()) #代替print e 来输出详细的异常信息
27 except Exception:
28 print(traceback.print_exc())
  最后遍历页数,调用函数。OK完成!
  1 for page in range(1,5): #这里设置想要爬取的页数
2 html = get_page(page)
3 #print(html)
4 print("第" + str(page) + "页提取完成")
  我们来看看最终的效果:
  
  二
  硒
  渴望学习的朋友可能还想看看Selenium是如何爬取AJAX动态加载的网页的。J哥自然会满足你的好奇心。于是赶紧新建了一个py文件,准备趁势而上,用Selenium把这个网站爬下来。
  首先,导入相关库。
  1from lxml import etree
2import time
3from selenium import webdriver
4from selenium. webdriver.support.wait import WebDriverWait
5from selenium.webdriver.support import expected_conditions as EC
6from selenium.webdriver.common.by import By
  然后,使用chromedriver驱动打开这个网站。
  1def main():
2 # 爬取首页url
3 url = "http://www.hshfy.sh.cn/shfy/gw ... ot%3B
4 # 定义谷歌webdriver
5 driver = webdriver.Chrome(&#39;./chromedriver&#39;)
6 driver.maximize_window() # 将浏览器最大化
7 driver.get(url)
  所以,我惊讶地发现报告了一个错误。以CET-6英语的词汇储备,J哥居然听懂了!可能是我的驱动和浏览器版本不匹配,只支持79版本的浏览器。
  J兄很郁闷,因为我以前用Selenium从来没有遇到过这种问题。J哥不甘心,打开谷歌浏览器查看版本号。
  
  我失去了它!都更新到了81版!遇到这种情况,请好奇的朋友等待J哥设置浏览器自动更新并重新下载最新驱动,下次再来听听Selenium爬虫吧。记得关注本公众号,不要错过精彩哦~
  综上所述,对于网络爬虫的AJAX动态加载,一般有两种方式:解析接口;硒。J兄推荐解析接口的方式。如果是解析json数据,最好是爬取。如果你不知道如何使用Selenium,让我们使用Selenium。

java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)

网站优化优采云 发表了文章 • 0 个评论 • 70 次浏览 • 2021-11-29 08:18 • 来自相关话题

  java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)
  下面的例子展示了如何使用 Jsoup 进行分析。在这种情况下,将获得博客花园首页的标题和第一页的博客列表文章。
  
  请看代码(在前面代码的基础上进行操作,如果不知道如何使用httpclient,请跳转页面阅读):
  引入依赖
  
org.jsoup
jsoup
1.12.1
  实现代码。在实现代码之前,先分析一下html结构。标题不用说了,文章列表呢?按浏览器的F12,查看页面元素的源代码。你会发现list是一个大div,id="post_list",每篇文章文章都是一个小div,class="post_item"
  
  然后就可以开始代码了,Jsoup的核心代码如下(整体源码会在文章的最后给出):
  /**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}
  根据上面的代码,你会发现我通过Jsoup.parse(String html)方法解析httpclient获取到的html内容获取Document,然后文档可以通过两种方式获取它的子元素:像js一样,它可以通过 getElementXXXX 获取。像 jquery 选择器一样传递 select() 方法。无论哪种方式都可以,我个人建议使用 select 方法。对于元素中的属性,比如超链接地址,可以使用 element.attr(String) 方法获取,对于元素的文本内容,可以使用 element.text() 方法获取。
  执行代码,查看结果(不得不感慨博客园的园友真是厉害。从上面对首页html结构的分析,到Jsoup分析的代码的执行,在这次文章)
  
  由于新的文章发布太快,上面的截图和这里的输出有些不同。
  三、Jsoup的其他用法
  我Jsoup除了可以发挥httpclient小哥的工作成果外,还可以自己动手,自己抓取页面,然后自己分析。上面已经展示了分析技巧,下面展示如何自己抓取页面。其实很简单。不同的是我直接拿到文档,不需要通过Jsoup.parse()方法解析。
  
  除了直接访问在线资源,我还可以分析本地资源:
  代码:
  public static void main(String[] args) {
try {
Document document = Jsoup.parse(new File("d://1.html"), "utf-8");
System.out.println(document);
} catch (IOException e) {
e.printStackTrace();
}
}
  四、Jsoup 另一个值得一提的功能
  你一定有过这样的经历。在你页面的文本框中,如果你输入了html元素,保存后页面布局很可能会乱七八糟。如果能过滤一下内容就完美了。
  碰巧我可以用 Jsoup 做到这一点。
  通过 Jsoup.clean 方法,使用白名单进行过滤。结果:
  unsafe: <p>博客园
safe:
  <a rel="nofollow">博客园</a></p>
  五、结论
  通过以上,大家都相信我很厉害了。不仅可以解析HttpClient抓取到的html元素,还可以自己抓取页面dom,还可以加载解析本地保存的html文件。
  另外,我可以通过白名单过滤字符串,过滤掉一些不安全的字符。
  最重要的是,以上所有函数的API调用都比较简单。
  ============华丽的分割线============
  码字不易,喜欢就​​去吧~~
  最后附上案例分析中博客园首页文章列表的完整源码:
  
  
  package httpclient_learn;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class HttpClientTest {

public static void main(String[] args) {
//1.生成httpclient,相当于该打开一个浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
//2.创建get请求,相当于在浏览器地址栏输入 网址
HttpGet request = new HttpGet("https://www.cnblogs.com/");
//设置请求头,将爬虫伪装成浏览器
request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
// HttpHost proxy = new HttpHost("60.13.42.232", 9999);
// RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
// request.setConfig(config);
try {
//3.执行get请求,相当于在输入地址栏后敲回车键
response = httpClient.execute(request);

//4.判断响应状态为200,进行处理
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//5.获取响应内容
HttpEntity httpEntity = response.getEntity();
String html = EntityUtils.toString(httpEntity, "utf-8");
System.out.println(html);

/**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}


} else {
//如果返回状态不是200,比如404(页面不存在)等,根据情况做处理,这里略
System.out.println("返回状态不是200");
System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//6.关闭
HttpClientUtils.closeQuietly(response);
HttpClientUtils.closeQuietly(httpClient);
}
}
}
  查看代码 查看全部

  java爬虫抓取动态网页(通过案例展示如何使用Jsoup进行解析案例中将获取博客园首页)
  下面的例子展示了如何使用 Jsoup 进行分析。在这种情况下,将获得博客花园首页的标题和第一页的博客列表文章。
  
  请看代码(在前面代码的基础上进行操作,如果不知道如何使用httpclient,请跳转页面阅读):
  引入依赖
  
org.jsoup
jsoup
1.12.1
  实现代码。在实现代码之前,先分析一下html结构。标题不用说了,文章列表呢?按浏览器的F12,查看页面元素的源代码。你会发现list是一个大div,id="post_list",每篇文章文章都是一个小div,class="post_item"
  
  然后就可以开始代码了,Jsoup的核心代码如下(整体源码会在文章的最后给出):
  /**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}
  根据上面的代码,你会发现我通过Jsoup.parse(String html)方法解析httpclient获取到的html内容获取Document,然后文档可以通过两种方式获取它的子元素:像js一样,它可以通过 getElementXXXX 获取。像 jquery 选择器一样传递 select() 方法。无论哪种方式都可以,我个人建议使用 select 方法。对于元素中的属性,比如超链接地址,可以使用 element.attr(String) 方法获取,对于元素的文本内容,可以使用 element.text() 方法获取。
  执行代码,查看结果(不得不感慨博客园的园友真是厉害。从上面对首页html结构的分析,到Jsoup分析的代码的执行,在这次文章)
  
  由于新的文章发布太快,上面的截图和这里的输出有些不同。
  三、Jsoup的其他用法
  我Jsoup除了可以发挥httpclient小哥的工作成果外,还可以自己动手,自己抓取页面,然后自己分析。上面已经展示了分析技巧,下面展示如何自己抓取页面。其实很简单。不同的是我直接拿到文档,不需要通过Jsoup.parse()方法解析。
  
  除了直接访问在线资源,我还可以分析本地资源:
  代码:
  public static void main(String[] args) {
try {
Document document = Jsoup.parse(new File("d://1.html"), "utf-8");
System.out.println(document);
} catch (IOException e) {
e.printStackTrace();
}
}
  四、Jsoup 另一个值得一提的功能
  你一定有过这样的经历。在你页面的文本框中,如果你输入了html元素,保存后页面布局很可能会乱七八糟。如果能过滤一下内容就完美了。
  碰巧我可以用 Jsoup 做到这一点。
  通过 Jsoup.clean 方法,使用白名单进行过滤。结果:
  unsafe: <p>博客园
safe:
  <a rel="nofollow">博客园</a></p>
  五、结论
  通过以上,大家都相信我很厉害了。不仅可以解析HttpClient抓取到的html元素,还可以自己抓取页面dom,还可以加载解析本地保存的html文件。
  另外,我可以通过白名单过滤字符串,过滤掉一些不安全的字符。
  最重要的是,以上所有函数的API调用都比较简单。
  ============华丽的分割线============
  码字不易,喜欢就​​去吧~~
  最后附上案例分析中博客园首页文章列表的完整源码:
  
  
  package httpclient_learn;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class HttpClientTest {

public static void main(String[] args) {
//1.生成httpclient,相当于该打开一个浏览器
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
//2.创建get请求,相当于在浏览器地址栏输入 网址
HttpGet request = new HttpGet("https://www.cnblogs.com/";);
//设置请求头,将爬虫伪装成浏览器
request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
// HttpHost proxy = new HttpHost("60.13.42.232", 9999);
// RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
// request.setConfig(config);
try {
//3.执行get请求,相当于在输入地址栏后敲回车键
response = httpClient.execute(request);

//4.判断响应状态为200,进行处理
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//5.获取响应内容
HttpEntity httpEntity = response.getEntity();
String html = EntityUtils.toString(httpEntity, "utf-8");
System.out.println(html);

/**
* 下面是Jsoup展现自我的平台
*/
//6.Jsoup解析html
Document document = Jsoup.parse(html);
//像js一样,通过标签获取title
System.out.println(document.getElementsByTag("title").first());
//像js一样,通过id 获取文章列表元素对象
Element postList = document.getElementById("post_list");
//像js一样,通过class 获取列表下的所有博客
Elements postItems = postList.getElementsByClass("post_item");
//循环处理每篇博客
for (Element postItem : postItems) {
//像jquery选择器一样,获取文章标题元素
Elements titleEle = postItem.select(".post_item_body a[class='titlelnk']");
System.out.println("文章标题:" + titleEle.text());;
System.out.println("文章地址:" + titleEle.attr("href"));
//像jquery选择器一样,获取文章作者元素
Elements footEle = postItem.select(".post_item_foot a[class='lightblue']");
System.out.println("文章作者:" + footEle.text());;
System.out.println("作者主页:" + footEle.attr("href"));
System.out.println("*********************************");
}


} else {
//如果返回状态不是200,比如404(页面不存在)等,根据情况做处理,这里略
System.out.println("返回状态不是200");
System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//6.关闭
HttpClientUtils.closeQuietly(response);
HttpClientUtils.closeQuietly(httpClient);
}
}
}
  查看代码

官方客服QQ群

微信人工客服

QQ人工客服


线