蜘蛛程序 网络爬虫 源代码
- 格式:docx
- 大小:23.41 KB
- 文档页数:7
网络爬虫的六种方式突然对网络爬虫特别感兴趣,所以就上网查询了下,发现这个特别好。
给大家分享下。
现在有越来越多的人热衷于做网络爬虫(网络蜘蛛),也有越来越多的地方需要网络爬虫,比如搜索引擎、资讯采集、舆情监测等等,诸如此类。
网络爬虫涉及到的技术(算法/策略)广而复杂,如网页获取、网页跟踪、网页分析、网页搜索、网页评级和结构/非结构化数据抽取以及后期更细粒度的数据挖掘等方方面面,对于新手来说,不是一朝一夕便能完全掌握且熟练应用的,对于作者来说,更无法在一篇文章内就将其说清楚。
因此在本篇文章中,我们仅将视线聚焦在网络爬虫的最基础技术——网页抓取方面。
说到网页抓取,往往有两个点是不得不说的,首先是网页编码的识别,另外一个是对网页脚本运行的支持,除此之外,是否支持以POST方式提交请求和支持自动的cookie管理也是很多人所关注的重要方面。
其实Java世界里,已经有很多开源的组件来支持各种各样方式的网页抓取了,包括上面提到的四个重点,所以说使用Java做网页抓取还是比较容易的。
下面,作者将重点介绍其中的六种方式。
HttpClientHttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。
(1)实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)(2)支持自动转向(3)支持 HTTPS 协议(4)支持代理服务器(5)支持自动的Cookies管理等Java爬虫开发中应用最多的一种网页获取技术,速度和性能一流,在功能支持方面显得较为底层,不支持JS脚本执行和CSS解析、渲染等准浏览器功能,推荐用于需要快速获取网页而无需解析脚本和CSS 的场景。
He ritri x是一个开源,可扩展的web爬虫项目。
H eritr ix设计成严格按照r obots.txt文件的排除指示和MET A rob ots标签。
htt p://c rawle r.arc hive.org/WebS PHINXWebS PHINX是一个Ja va类包和Web爬虫的交互式开发环境。
W eb爬虫(也叫作机器人或蜘蛛)是可以自动浏览与处理Web页面的程序。
W ebSPH INX由两部分组成:爬虫工作平台和Web SPHIN X类包。
http://www.cs.c mu.ed u/~rc m/web sphin x/W ebLec hWeb Lech是一个功能强大的Web站点下载与镜像工具。
它支持按功能需求来下载web站点并能够尽可能模仿标准Web浏览器的行为。
WebL ech有一个功能控制台并采用多线程操作。
http://we blech.sour cefor ge.ne t/A raleArale主要为个人使用而设计,而没有像其它爬虫一样是关注于页面索引。
Arale能够下载整个web站点或来自w eb站点的某些资源。
Arale还能够把动态页面映射成静态页面。
htt p://w eb.ti scali.it/_flat/arale.jsp.htmlJ-Sp iderJ-Spi der:是一个完全可配置和定制的WebSpide r引擎.你可以利用它来检查网站的错误(内在的服务器错误等),网站内外部链接检查,分析网站的结构(可创建一个网站地图),下载整个We b站点,你还可以写一个JSpi der插件来扩展你所需要的功能。
spider简介以及基础⽅法(第⼀章)查看⽹站结构import builtwithprint builtwith.parse("")最原始的爬⾍import urllib2def download(url):print"down", urltry:html = urllib2.urlopen(url).read()except urllib2.URLError as e:print"download error", e.reasonhtml = Nonereturn htmlprint download("")增加递归import urllib2def download(url, num_retries):print"down", urltry:html = urllib2.urlopen(url).read()except urllib2.URLError as e:print"download error", e.reasonhtml = Noneif hasattr(e, "code") and 500 <= e.code <600:# recursively retry 5xx HTTP errorsreturn download(url, num_retries-1)return htmlprint download("",2)⽤户代理import urllib2def download(url, user_agent = "wswp", num_retries = 2):print"down",urlheaders = {"User_agent":user_agent}request = urllib2.Request(url, headers=headers)try:html = urllib2.urlopen(request).read()except urllib2.URLError as e:print"download error", e.reasonhtml = Noneif hasattr(e, "code") and 500 <= e.code < 600:# recursively retry 5xx Http errorsreturn download(url, user_agent, num_retries-1)return htmlprint download("")运⽤上述的download脚本读不出标签(问题:可能是标签不存在)import redef crawl_sitemap(url):# download the sitemapsite_map = download(url)print"site_map", site_map# extract the sitemap linkslinks = re.findall('<loc>(.*?)</loc>', site_map)print'links', links# download each linkfor link in links:html = download(links)crawl_sitemap("/sitmap.xml")对ID进⾏遍历,直到出错为⽌import itertools # ⽆限迭代器for page in itertools.count(1):url = "/view/-%d" % pagehtml = download(url)if html is None:breakelse:pass若ID出现中间被删除,就⽆法连续⾃动退出,为了解决这种问题,脚本加⼊连续判断5次,若都为空,就结束import itertoolsmax_error = 5 # 最⼤错误值num_error = 0 # 现有错误for page in itertools.count(1):url = "/view/-%d" % pagehtml = download(url)if html is None:num_error += 1if num_error == max_error:break# 若连续5次错误,程序结束else:num_error = 0 # 若错误不是连续的,则变量归0链接爬⾍import redef get_link(html):"""return a list of links from html"""webpage_regex = pile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE) # re.IGNORECASE 忽略⼤⼩写return webpage_regex.findall(html)def link_crawler(seed_url, link_regex):""""""crawl_queue = [seed_url]while crawl_queue:url = crawl_queue.pop()html = download(url)for link in get_link(html):if re.match(link_regex, link):crawl_queue.append(link)python HTTP模块requests 来实现⽀持代理的功能import urlparseproxy = ""opener = urllib2.build_opener()proxy_params = {urlparse.urlparse(url).scheme: proxy}opener.add_handler(urllib2.ProxyHandler(proxy_params))response = opener.open(request)新版本的download函数def download(url, user_agent="wswp", proxy=None, num_retries=2):print"DownLoading", urlheaders = {"User-agent": user_agent}request = urllib2.Request(url, headers=headers)opener = urllib2.build_opener()if proxy:proxy_params = {urlparse.urlparse(url).scheme: proxy}opener.add_handler(urllib2.ProxyHandler(proxy_params))try:html = opener.open(request).read()except urllib2.URLError as e:print"download error", e.reasonhtml = Noneif num_retries > 0:if hasattr(e, "code") and 500 <= e.code <600:# retry 5xx http errorhtml = download(url, user_agent, proxy, num_retries-1)return html下载限速(两次下载中添加延时)import timeimport datetimeclass Throttle:"""Add a delay between downloads to the same domain"""def__init__(self, delay):# amount of delay between downloads for each domainself.delay = delay# timestamp of when a domain was last accessedself.domains = {}def wait(self, url):domain = urlparse.urlparse(url).netloclast_accessed = self.domains.get(domain)if self.delay > 0 and last_accessed is not None:sleep_secs = self.delay - (datetime.datetime.now() - last_accessed).seconds if sleep_secs > 0:# domain has been accessd recently# so need to sleeptime.sleep(sleep_secs)# update the last accessed timeself.domains[domain] = datetime.datetime.now()实例操作延时throttle = Throttle(delay)throttle.wait(url)result = download(url, headers, proxy=proxy, num_retries=num_retries)"""爬⾍陷阱(有些⽹站会动态⽣成内容如:下⼀⽉,下⼀年这种⽆限递归)⽅法:添加深度限制,修改seen变量(该变量原本只记录访问过的链接,现在修改成为⼀个字典,增加了页⾯深度记录)"""def link_crawler(... , max_depth=2):max_depth = 2...depth = seen[url]if depth != max_depth:for link in links:if link not in seen:seen[link] = depth + 1crawl_queue.append(link)"""禁⽤该功能把max_depth设成负数就永远不会相等"""调⽤最终版本seed_url = "/index"link_regex = "/(index|view)"link_crawler(seed_url, link_regex, user_agent="BadCrawler") # user_agent="BadCrawler"⽤户代理被屏蔽程序运⾏不了link_crawler(seed_url, link_regex, max_depth=1) # 这是使⽤默认⽤户代理的,深度为1。
Python爬虫项目实战源代码集锦为了满足标题描述的内容需求,下面是一些Python爬虫项目实战的源代码示例,供参考和学习。
1. 爬取网页数据import requests# 发送HTTP请求获取网页内容response = requests.get(url)content = response.text# 解析网页内容# ...# 提取所需信息# ...# 存储数据# ...2. 爬取图片import requests# 发送HTTP请求获取图片资源response = requests.get(image_url)# 保存图片到本地with open('image.jpg', 'wb') as f:f.write(response.content)3. 爬取动态网页from selenium import webdriver # 启动浏览器驱动driver = webdriver.Chrome()# 打开动态网页driver.get(url)# 等待动态内容加载完成# ...# 提取所需信息# ...# 存储数据# ...4. 登录网站并获取数据import requests# 登录网站login_data = {'username': 'your_username','password': 'your_password'}session = requests.Session() session.post(login_url, data=login_data) # 发送登录后的请求response = session.get(url)# 解析网页内容# ...# 提取所需信息# ...# 存储数据# ...5. 反爬虫处理import requestsfrom fake_useragent import UserAgent # 构造随机HTTP请求头user_agent = UserAgent().random# 发送带有伪装的HTTP请求headers = {'User-Agent': user_agent}response = requests.get(url, headers=headers)# 解析网页内容# ...# 提取所需信息# ...# 存储数据# ...以上是一些Python爬虫项目实战源代码的简单示例,可以根据具体项目的需求进行修改和扩展。
python 爬虫常规代码Python爬虫常规代码是指用Python编写的用于网页数据抓取和提取的代码。
爬虫是一种自动化程序,可以模拟人类在网页浏览器中的行为,从而获取所需的信息。
在这篇文章中,我们将一步一步地回答关于Python 爬虫常规代码的问题,帮助读者了解如何编写自己的爬虫程序。
第一步:安装Python和必要的库首先,我们需要安装Python和一些必要的库来编写爬虫代码。
Python 是一种流行的编程语言,可以用于开发各种应用程序,包括爬虫。
对于Python的版本,我们建议使用Python 3.x。
然后,我们需要安装一些常用的爬虫库,例如requests和beautifulsoup4。
可以使用pip命令来安装它们:pip install requestspip install beautifulsoup4第二步:发送HTTP请求在编写爬虫代码之前,我们首先需要发送HTTP请求以获取网页的内容。
这可以使用requests库来实现。
以下是一个简单的例子:pythonimport requestsurl = "response = requests.get(url)if response.status_code == 200:content = response.textprint(content)在这个例子中,我们首先指定了要访问的URL,然后使用requests库的get方法发送一个GET请求。
如果响应的状态码是200,表示请求成功,我们就可以从response对象中获取网页内容,并打印出来。
第三步:解析网页内容获取网页的原始内容后,我们通常需要解析网页,提取所需的信息。
这可以使用beautifulsoup4库来实现。
下面是一个示例:pythonfrom bs4 import BeautifulSoup# 假设content是之前获取的网页内容soup = BeautifulSoup(content, "html.parser")# 使用soup对象进行解析在这个例子中,我们首先导入了BeautifulSoup类并创建了一个soup对象,该对象将用于解析网页内容。
Python网络爬虫实践教程一、什么是网络爬虫网络爬虫,也称为网络蜘蛛或网络机器人,是一种自动获取互联网信息的程序工具。
通过模拟浏览器行为,爬虫程序可以访问网页、提取网页中的数据,在大规模数据采集、搜索引擎、数据分析等领域发挥着重要作用。
二、网络爬虫的基本原理网络爬虫的基本原理是通过发送HTTP请求,并解析响应得到的HTML文档来获取网页数据。
首先,我们需要使用Python中的requests库发送网络请求,并获得服务器的响应。
然后,通过解析HTML文档,提取出我们需要的数据。
三、准备工作在开始编写网络爬虫之前,我们需要安装Python以及相关的库。
首先,需要安装Python解释器和pip包管理工具。
然后,使用pip安装requests、beautifulsoup和lxml等库。
四、发送HTTP请求在编写爬虫程序之前,我们需要了解如何使用Python发送HTTP请求。
使用requests库发送GET请求非常简单,只需要调用get方法,并提供目标网址即可。
如果需要发送POST请求,同样使用post方法,并在参数中传递需要提交的数据。
五、解析HTML文档解析HTML文档是爬虫中非常重要的一步。
Python提供了多种解析HTML的库,其中比较常用的是beautifulsoup和lxml。
通过指定解析器,我们可以轻松地提取出HTML文档中的各个元素,并进行进一步的处理。
六、处理反爬机制为了阻止爬虫程序的访问,许多网站采取了反爬机制,例如设置验证码、限制IP访问频率等。
对于这些反爬措施,我们可以通过使用代理IP、设置请求头信息、使用验证码识别技术等方法来绕过。
七、数据存储与分析在爬虫过程中,我们通常需要将获取的数据进行存储和分析。
常用的数据存储方式包括将数据保存到数据库、文本文件、Excel 表格或者CSV文件中。
而要对数据进行分析,可以使用Python中的数据分析库,如pandas、numpy等。
八、实践案例:爬取豆瓣电影数据为了更好地理解网络爬虫的实践过程,我们以爬取豆瓣电影数据为例进行讲解。
搜索引擎/网络蜘蛛程序代码关于搜索引擎的相关知识国外开发的相关程序
一、Nutch
官方网站
中文站点
最新版本:NutchReleased
Nutch是一个开源Java实现的搜索引擎。
它提供了咱们运行自己的搜索引擎所需的全数工具,能够成立自己内部网的搜索引擎,也能够针对整个网络成立搜索引擎。
自由(Free)而免费(Free)。
二、Lucene
官方网站
中文站点
Lucene是apache软件基金会jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包[用Java写的],即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部份文本分析引擎(英文与德文两种西方语言)。
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或是以此为基础成立起完整的全文检索引擎。
3、Larbin:
larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人SébastienAilleret 独立开发。
larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供普遍的数据来源。
蜘蛛程序的名词解释是蜘蛛程序的名词解释是“网络爬虫”网络爬虫,又称为蜘蛛程序、网络机器人,是一种能够自动浏览互联网信息的计算机程序。
它们为搜索引擎和其他应用程序收集网页,并将这些网页内容保存在数据库中,以便后续使用和分析。
网络爬虫的工作原理类似于现实生活中的蜘蛛。
它们从一个起始点(通常是一个特定的网页)开始,根据预设的规则和策略,沿着网页之间的链接不断爬行,将访问到的网页内容保存下来。
这些链接可以是超链接,也可以是表单提交等方式。
通过这种方式,网络爬虫可以覆盖并获取大量的网页信息。
网络爬虫的应用广泛,其中最常见的应用就是搜索引擎。
搜索引擎通过网络爬虫收集尽可能多的网页,然后对这些网页进行处理和索引,以便用户能够方便地找到所需的信息。
网络爬虫通过分析网页的标题、内容、链接等信息,搜索引擎可以建立起一个庞大的网页索引库,为用户提供准确、全面的搜索结果。
除了搜索引擎,网络爬虫还被广泛应用于数据挖掘和其他领域的研究中。
通过爬取互联网上的大量数据,研究人员可以对数据进行分析和挖掘,从中发现有价值的信息和规律。
例如,在市场调研中,研究人员可以爬取相关行业的网页数据来了解市场动态和竞争对手的情况。
在金融领域,网络爬虫可以帮助投资者获取最新的股票数据,并进行分析和预测。
然而,网络爬虫也面临着一些挑战和限制。
首先,由于互联网上的信息量庞大,网络爬虫可能无法有效地覆盖所有的网页。
其次,有些网站会设置反爬虫机制,限制爬虫程序的访问,并对其进行识别和封锁。
此外,网络爬虫在访问网页时需要消耗大量的带宽和计算资源,对服务器造成一定的负担,因此应该遵守相关的爬虫规范和道德准则。
为了提高网络爬虫的效率和准确性,研究人员不断提出新的算法和技术。
例如,基于机器学习和自然语言处理的技术可以帮助爬虫程序更好地理解和解析网页内容,从而提高数据的质量。
此外,分布式爬虫系统可以同时运行多个爬虫程序,从而加快数据的收集和处理速度。
总的来说,网络爬虫是一种能够自动浏览互联网信息的计算机程序。
有一天突然看了htmlparser工具包发现果然强大。
由于不是很熟悉所以下面代码或许写的有点烂。
首先做准备工作先写一个实体beanpackage bean; import java.util.Date;/*** @author Jeson* blog * @date:Oct 9, 2009 3:09:19 PM* @version :1.0**/publicclass Artical {private String title;private String body;private String link;private String author;private String [] tags;private Date dCreate;public String getTitle() {return title;}publicvoid setTitle(String title) {this.title = title;}public String getBody() {return body;}publicvoid setBody(String body) {this.body = body;}public String getLink() {return link;}publicvoid setLink(String link) {this.link = link;}public String getAuthor() {return author;}publicvoid setAuthor(String author) {this.author = author;}public String[] getTags() {return tags;}publicvoid setTags(String[] tags) {this.tags = tags;}public Date getDCreate() {return dCreate;}publicvoid setDCreate(Date create) {dCreate = create;}}2 写一个我们下面要用到的字符串处理类package util;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.util.regex.Matcher;import java.util.regex.Pattern;/*** @author Jeson* blog * @date:Oct 9, 2009 3:09:19 PM * @version:1.0 */publicclass StringUtil {/*** 使用正则匹配字符串** @param regex* 正则表达式* @param txt* 要验证的字符串* @return匹配则返回真否则返回假*/publicstaticboolean useRegex(String regex, String txt) {Pattern p = pile(regex);Matcher m = p.matcher(txt);return m.matches();}/*** 使用正则匹配字符串** @param regex* 正则表达式 ** @param index* 要取第几个元素* @param txt* 要验证的字符串* @return返回匹配的字符串*/publicstatic String getByRegex(String regex, int index, String txt) {Pattern p = pile(regex);Matcher m = p.matcher(txt);if (m.find()) {return m.group(index);}returnnull;}/*** 使用正则匹配字符串** @param regex* 正则表达式 ** @param index* 要取第几个元素* @param txt* 要验证的字符串* @return返回匹配的字符串数组*/publicstatic String [] getStringsByRegex(String regex, int[] index, String txt) {String res [] = new String[index.length];Pattern p = pile(regex);Matcher m = p.matcher(txt);if (m.find()) {for(int i : index){res[i] = m.group(i);}}return res;}}3 下面是我们的核心类他会去抓取cnblogs的页面并保存package test; import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import org.htmlparser.NodeFilter;import org.htmlparser.Parser;import org.htmlparser.filters.HasAttributeFilter; import org.htmlparser.util.NodeList;import bean.Artical;import util.StringUtil;/*** @author Jeson* @blog * @date:Oct 9, 2009 1:08:10 PM* @version :1.0**/publicclass Parse {privatestaticfinalint MAX_PAGE = 20;privatefinal String ENCODING = "UTF-8";/*** @param args*/publicstaticvoid main(String[] args) {try {for(int i=1;i<MAX_PAGE;i++){new Parse().testAttribute(i);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}privatevoid testAttribute(int pa) throws Exception{System.out.println("————开始解析页面:"+pa);Parser p = new Parser();p.setURL("/cate/java/?page="+pa);p.setEncoding("UTF-8");NodeFilter filter = new HasAttributeFilter("class","titlelnk");NodeList list = p.extractAllNodesThatMatch(filter);System.out.println(list.size());int cou = 0;for(int i=0 ; i<list.size();i++){String html = list.elementAt(i).toHtml(true);int [] index = {0,1,2};String [] bs = StringUtil.getStringsByRegex("<aclass=\\"titlelnk\\" href=\\"(.*)\\" target=\\"_blank\\">(.*)</a>", index, html);String title = bs[2];String url = bs[1];System.out.println(url);String content = getContent(bs[1]);if(content == null || "".equals(content)){continue;}Artical art = new Artical();art.setTitle(title);art.setBody(content);art.setLink(url);createFile(art);System.out.println("=========="+(i+1)+"============");System.out.println("title==>"+bs[2]);System.out.println("url==>"+bs[1]);System.out.println("content==>"+getContent(bs[1]));System.out.println("======================");System.out.println();cou++;}System.out.println("over"+cou);}private String getContent(String url) throws Exception{Parser p = new Parser();p.setURL(url);p.setEncoding(ENCODING);NodeFilter filter = new HasAttributeFilter("class","post");NodeList list = p.extractAllNodesThatMatch(filter);String a = list.toHtml();return a;}privatevoid createFile(Artical art){try {File d = new File("d:\\\\cnblog");if(!d.exists()){d.mkdir();}File f = newFile("d:\\\\cnblog\\\\"+art.getTitle()+".html");if(!f.exists()){f.createNewFile();System.out.println("——–>"+art.getTitle()+"文件已经创建");}OutputStream file = new FileOutputStream(f.getPath());file.write(art.getBody().getBytes());file.flush();file.close();System.out.println("文件写入完毕,地址"+f.getPath());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();System.out.println(art.getLink()+" "+art.getTitle()+"文件写入失败");}}}。