蜘蛛程序 网络爬虫 源代码
网络爬虫的六种方式

网络爬虫的六种方式突然对网络爬虫特别感兴趣,所以就上网查询了下,发现这个特别好。
给大家分享下。
现在有越来越多的人热衷于做网络爬虫(网络蜘蛛),也有越来越多的地方需要网络爬虫,比如搜索引擎、资讯采集、舆情监测等等,诸如此类。
网络爬虫涉及到的技术(算法/策略)广而复杂,如网页获取、网页跟踪、网页分析、网页搜索、网页评级和结构/非结构化数据抽取以及后期更细粒度的数据挖掘等方方面面,对于新手来说,不是一朝一夕便能完全掌握且熟练应用的,对于作者来说,更无法在一篇文章内就将其说清楚。
因此在本篇文章中,我们仅将视线聚焦在网络爬虫的最基础技术——网页抓取方面。
说到网页抓取,往往有两个点是不得不说的,首先是网页编码的识别,另外一个是对网页脚本运行的支持,除此之外,是否支持以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简介以及基础方法(第一章)

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。
网络爬虫 1

广度优先搜索策略是指在抓取过程中,在完成当前层次的搜索后,才进行下一层次的搜索。该算法的设计和实现相对简单。在目前为覆盖尽可能多的网页,一般使用广度优先搜索方法。也有很多研究将广度优先搜索策略应用于聚焦爬虫中。其基本思想是认为与初始URL在一定链接距离内的网页具有主题相关性的概率很大。另外一种方法是将广度优先搜索与网页过滤技术结合使用,先用广度优先策略抓取网页,再将其中无关的网页过滤掉。这些方法的缺点在于,随着抓取网页的增多,大量的无关网页将被下载并过滤,算法的效率将变低。
编辑本段网页分析算法
网页分析算法可以归纳为基于网络拓扑、基于网页内容和基于用户访问行为三种类型。
基于网络拓扑的分析算法
基于网页之间的链接,通过已知的网页或数据,来对与其有直接或间接链接关系的对象(可以是网页或网站等)作出评价的算法。又分为网页粒度、网站粒度和网页块粒度这三种。 1 网页(Webpage)粒度的分析算法 PageRank和HITS算法是最常见的链接分析算法,两者都是通过对网页间链接度的递归和规范化计算,得到每个网页的重要度评价。PageRank算法虽然考虑了用户访问行为的随机性和Sink网页的存在,但忽略了绝大多数用户访问时带有目的性,即网页和链接与查询主题的相关性。针对这个问题,HITS算法提出了两个关键的概念:权威型网页(authority)和中心型网页(hub)。 基于链接的抓取的问题是相关页面主题团之间的隧道现象,即很多在抓取路径上偏离主题的网页也指向目标网页,局部评价策略中断了在当前路径上的抓取行为。文献[21]提出了一种基于反向链接(BackLink)的分层式上下文模型(Context Model),用于描述指向目标网页一定物理跳数半径内的网页拓扑图的中心Layer0为目标网页,将网页依据指向目标网页的物理跳数进行层次划分,从外层网页指向内层网页的链接称为反向链接。 2 网站粒度的分析算法 网站粒度的资源发现和管理策略也比网页粒度的更简单有效。网站粒度的爬虫抓取的关键之处在于站点的划分和站点等级(SiteRank)的计算。SiteRank的计算方法与PageRank类似,但是需要对网站之间的链接作一定程度抽象,并在一定的模型下计算链接的权重。? 网站划分情况分为按域名划分和按IP地址划分两种。文献[18]讨论了在分布式情况下,通过对同一个域名下不同主机、服务器的IP地址进行站点划分,构造站点图,利用类似PageRank的方法评价SiteRank。同时,根据不同文件在各个站点上的分布情况,构造文档图,结合SiteRank分布式计算得到DocRank。文献[18]证明,利用分布式的SiteRank计算,不仅大大降低了单机站点的算法代价,而且克服了单独站点对整个网络覆盖率有限的缺点。附带的一个优点是,常见PageRank 造假难以对SiteRank进行欺骗。? 3 网页块粒度的分析算法 在一个页面中,往往含有多个指向其他页面的链接,这些链接中只有一部分是指向主题相关网页的,或根据网页的链接锚文本表明其具有较高重要性。但是,在PageRank和HITS算法中,没有对这些链接作区分,因此常常给网页分析带来广告等噪声链接的干扰。在网页块级别(Block?level)进行链接分析的算法的基本思想是通过VIPS网页分割算法将网页分为不同的网页块(page block),然后对这些网页块建立page?to?block和block?to?page的链接矩阵,?分别记为Z和X。于是,在page?to?page图上的网页块级别的PageRank为?W?p=X×Z;?在block?to?block图上的BlockRank为?W?b=Z×X。?已经有人实现了块级别的PageRank和HITS算法,并通过实验证明,效率和准确率都比传统的对应算法要好。?
Python爬虫项目实战源代码集锦

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网络爬虫技术 第1章 Python爬虫环境与爬虫介绍

大数据挖掘专家
12
网站反爬虫的目的与手段
3. 通过验证码校验反爬
有部分网站不论访问频度如何,一定要来访者输入验证 码才能继续操作。例如12306网站,不管是登陆还是购 票,全部需要验证验证码,与访问频度无关。
大数据挖掘专家
13
网站反爬虫的目的与手段
4. 通过变换网页结构反爬
一些社交网站常常会更换网页结构,而爬虫大部分情况下都需要通过网页结构来解析需要的数据,所以这种 做法也能起到反爬虫的作用。在网页结构变换后,爬虫往往无法在原本的网页位置找到原本需要的内容。
树形式,将表单区分为单属性表单和多属性表单,分别进行处理,从中提取表单各字段值。
大数据挖掘专家
7
爬虫的合法性与robot.txt协议
1. 爬虫的合法性
目前,多数网站允许将爬虫爬取的数据用于个人使用或者科学研究。但如果将爬取的数据用于其他用途,尤 其是转载或者商业用途,严重的将会触犯法律或者引起民事纠纷。 以下两种数据是不能爬取的,更不能用于商业用途。 ➢ 个人隐私数据:如姓名、手机号码、年龄、血型、婚姻情况等,爬取此类数据将会触犯个人信息保护法。 ➢ 明确禁止他人访问的数据:例如用户设置了账号密码等权限控制,进行了加密的内容。 还需注意版权相关问题,有作者署名的受版权保护的内容不允许爬取后随意转载或用于商业用途。
11
网站反爬虫的目的与手段
2. 通过访问频度反爬
➢ 普通用户通过浏览器访问网站的速度相对爬虫而言要慢的多,所 以不少网站会利用这一点对访问频度设定一个阈值,如果一个IP 单位时间内访问频度超过了预设的阈值,将会对该IP做出访问限 制。
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网络爬虫实践教程

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等。
八、实践案例:爬取豆瓣电影数据为了更好地理解网络爬虫的实践过程,我们以爬取豆瓣电影数据为例进行讲解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
有一天突然看了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()+"文件写入失败");}}}。