网页防抓取的一个思路以及实现

能搜到的 方法,无外乎判断 Http_referer 是否来源于本站和在网页里换行和回车后面添加本站名称和随机字符串。这两个方法对于略懂http协议和正则替换的兄弟来说,完全没用。对于我所知的和网上常用的几种方法具体分析如下:

1 判断http_referer 

http_referer是http头中的一段,不管使用VB/VC 的 winsock / inet transfer 控件,还是 使用asp服务器就可以用的 xmlHttpRequest 对象 ( for ajax ) , 抑或是php socket 、python urllib2, 都可以轻易的修改http header , 从而直接修改 http_referer的值。最偷懒的做法就是,把http_referer赋值为你的网站根url或访问的页面url。VB 中的 WebBrowser 控件更是不存在这个问题……大不了抓的慢一些就是了

此方法唯一有效的,可能对采用Adodb.Stream对象的抓取

2 加入随机字串/本站名称/url

对于固定字串,如本站名称和url,很多成型的网页采集程序都直接提供选项可以替换掉,实现起来也很容易。被采集方由于有在页面内放置不可见元素和堆砌关键字的嫌疑,有可能还会被搜索引擎认为作弊,这招很不可取~

对于随机字串,直接用字符串替换是不可以的,但是如果结合页面源码合理的运用正则表达式,一样可以破掉。比如:匹配 [/w]{,16}<br> ,替换为空,就可以删掉处于<br>之前的16位随机字母、数字字符串

3 在网页内加入能中断页面运行的脚本

在网页中加入 诸如 <script>alert("xxx")</script> 之类的脚本,用以阻断页面执行和显示。想出这个方法来的兄弟一定很bt~ 但是又有些可笑。只要不是抓完就直接显示页面的,这个方法根本没用。具体原因不再多说。而且这样对于被采集方网站的用户体验是个很坏的方面。

-------------------------------------------------------------------------------------------------

4 我的方法

前几日要求写一个放采集的程序。要求使一个打印内容的列表页面防采集。前思后想,认为只有一个办法,就是打乱表格的输出次序,采用随机顺序输出,在客户端使用js操作dom调换顺序。这样,服务器端输出的html中的表格非常的乱,但是客户查看和打印时又能正常显示。缺点是,正确的顺序依然要输出到页面上,如果采集方根据这个规律也将表格内容重新排序,仍然是可以读取的。

实现方法如下

 

<%function swap(byref a,byref b)
    
dim c
    c 
= a
    a 
= b
    b 
= c
end function
    
dim nam,tempRND,orders
    
    
redim orders(nRS + 1)
    
redim order(UBound(aRS,1))
    orders(
0= join(array(1,2,3,4,5,6,7,8,9,0),",")
    
    
randomize
    
rnd()
    
    i 
= 0
    
    
do while i <= nRS
        
        
for j = 0 to ubound(order)
            order(j) 
= j
        
next
        
for j = 0 to ubound(order)' step 2
            tempRND = int(rnd() * (UBound(order) + 1))
            
call swap(order(j),order(tempRND))
        
next
        orders(i 
+ 1= join(order,",")
  %
>
  
<tr>
      
<%
'          for j = 0 to UBound(order)
            response.write "<td >"
            response.Write aRS(order(j),i)
            response.write 
"</td>"
        
next
'        Response.write "</tr><tr>"
%>
  
</tr>
<
        i 
= i + 1
    
loop
%
>
<script>
var aOrd = [[<%= join(orders,"],[") %>]];
reOrder("tblList",aOrd);
</script>

客户端重新组合方法如下:

 

function reOrder(sObj,aOrder)
{
  
var o = document.getElementById(sObj).childNodes[0];
  
{
    
try{
      
var t = o.childNodes.length;
    }
catch(E){
      alert(E.description);
      
return;
    }

  }

  
for(var i = 1; i < o.childNodes.length ;i++){
    
var aReOrder = new Array();
    
var tr = o.childNodes[i];
    
for(var j = 0; tr.hasChildNodes() ;j++){
      aReOrder[aOrder[i][j]] 
= tr.removeChild(tr.childNodes[0]);
    }

    
for(var j = 0; j < aReOrder.length;j++){
      tr.appendChild(aReOrder[j]);
    }

  }

}

</script>

 

虽然这个不是完全一劳永逸的方法,至少可以难倒大批的不会js的程序员……

<think>嗯,用户想生成一个专业的爬虫代码,运行后能够实现粘贴网址就能爬取。首先,我需要理解用户的需求。他们可能希望有一个用户友好的爬虫工具,不需要每次都修改代码,而是通过输入网址来启动爬取。这可能涉及到用户输入的处理、网络请求、异常处理以及数据存储等方面。 接下来,我得考虑使用哪个编程语言。Python是比较常见的选择,因为它有丰富的库,比如Requests和Scrapy。不过用户可能希望一个简单直接的脚本,所以可能用Requests和BeautifulSoup组合更合适。Scrapy虽然强大,但配置起来稍微复杂一些,对于新手可能不够友好。 然后,功能点需要明确。用户需要粘贴网址,所以代码应该能接受用户的输入。然后发送HTTP请求获取网页内容,这里要考虑异常处理,比如网络错误、超时、无效URL等。接着是解析HTML,提取所需数据。用户可能没有指定具体的数据,所以可能需要一个通用的选择器,或者让用户自定义。但根据问题描述,用户可能希望一个示例,比如提取标题和正文,或者所有的链接。 存储部分,可能需要保存到文件,比如txt或csv。同时,要处理相对路径的问题,将链接转换为绝对URL。还有去重,避免重复爬取相同的页面。可能需要维护一个已爬取的URL集合。 然后,代码结构需要模块化,比如使用函数处理不同的部分。例如,fetch_url函数处理请求,parse_content处理解析,save_data处理存储。还要考虑用户代理设置,避免被网站屏蔽,遵守robots.txt。不过用户可能暂时不需要考虑这些高级功能,但作为专业代码,应该包含基本的礼貌爬取,比如设置User-Agent和延迟。 现在,可能的步骤是: 1. 获取用户输入的URL。 2. 发送请求,获取响应。 3. 解析响应内容,提取数据。 4. 保存数据到文件。 5. 处理异常情况,比如超时、404错误等。 需要用到requests库,beautifulsoup4,以及urllib.parse来处理URL。还要考虑编码问题,自动检测页面的编码。可能需要使用生成器或者类来维护状态,比如已爬取的URL集合。 然后,代码示例部分,应该包括异常处理,比如try-except块,处理requests可能抛出的异常。使用BeautifulSoup来解析,提取标题和段落文本。存储为txt文件,以时间戳命名避免覆盖。同时,将相对链接转换为绝对链接,并提取出来,可能作为后续扩展,比如爬取整个网站的基础。 用户可能还需要安装依赖的提示,比如pip安装requests和beautifulsoup4。此外,注意事项部分需要提醒遵守法律法规,尊重robots.txt,设置延迟,代理等。 可能遗漏的点:没有处理JavaScript渲染的页面,这时候需要Selenium或Playwright,但用户的问题可能不需要这么复杂。此外,代码是否支持递归爬取?用户的问题可能只是单个页面的爬取,所以示例可能不需要递归,但可以提到如果需要爬取整个网站,可以扩展代码,使用队列等结构。 最后,测试代码是否工作,比如输入一个URL,看是否能正确保存文件。同时,检查代码是否符合PEP8规范,变量命名是否清晰,函数是否有文档字符串。 总结,代码结构应该包括: - 导入必要的库 - 定义函数:获取URL内容 - 定义函数:解析内容 - 定义函数:保存数据 - 主程序:获取用户输入,调用函数,处理异常 - 输出结果和保存路径 可能需要添加日志记录,但为了简洁,暂时用print语句。同时,超时设置,比如10秒,避免长时间等待。 现在,将这些思路整合成一个清晰的步骤,用中文回答,结构分明,代码正确,并且有解释和注意事项。</think>我将为您设计一个基于Python的专业网页爬虫框架,包含模块化设计、异常处理和智能解析功能。以下是分步实现方案: 一、基础环境配置 ```python # 安装依赖库 # pip install requests beautifulsoup4 urllib3 python-dateutil ``` 二、核心代码架构 ```python import requests from urllib.parse import urljoin, urlparse from bs4 import BeautifulSoup import re from datetime import datetime import time class ProfessionalCrawler: def __init__(self): self.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept-Language': 'en-US,en;q=0.9', 'Accept-Encoding': 'gzip, deflate, br' } self.visited_urls = set() self.timeout = 10 self.max_retries = 3 def is_valid_url(self, url): """验证URL格式有效性""" parsed = urlparse(url) return parsed.scheme in ('http', 'https') and parsed.netloc != '' def fetch_content(self, url): """智能获取网页内容""" for _ in range(self.max_retries): try: response = requests.get(url, headers=self.headers, timeout=self.timeout) response.encoding = self.detect_encoding(response) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: print(f"请求失败: {e}") time.sleep(2) return None def detect_encoding(self, response): """自动检测编码""" if response.encoding == 'ISO-8859-1': return response.apparent_encoding return response.encoding def parse_content(self, html, base_url): """高级内容解析""" soup = BeautifulSoup(html, 'lxml') # 提取结构化数据 data = { 'title': soup.title.string.strip() if soup.title else '', 'meta_description': soup.find('meta', attrs={'name': 'description'})['content'] if soup.find('meta', attrs={'name': 'description'}) else '', 'main_content': self._extract_main_content(soup), 'links': self._extract_links(soup, base_url), 'images': [urljoin(base_url, img['src']) for img in soup.find_all('img') if img.get('src')] } return data def _extract_main_content(self, soup): """智能正文提取""" # 优先检测文章标签 article = soup.find('article') if article: return article.get_text().strip() # 备用方案:通过常见内容模式匹配 content_patterns = ['.post-content', '.article-body', '#content'] for pattern in content_patterns: element = soup.select_one(pattern) if element: return element.get_text().strip() # 最终回退方案 return soup.body.get_text().strip() if soup.body else '' def _extract_links(self, soup, base_url): """提取并规范化链接""" links = set() for link in soup.find_all('a', href=True): absolute_url = urljoin(base_url, link['href']) if self.is_valid_url(absolute_url): links.add(absolute_url) return list(links) def save_data(self, data, format='txt'): """多格式存储功能""" timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') filename = f"crawled_data_{timestamp}.{format}" with open(filename, 'w', encoding='utf-8') as f: if format == 'txt': f.write(f"标题: {data['title']}\n") f.write(f"描述: {data['meta_description']}\n") f.write("\n正文内容:\n") f.write(data['main_content']) elif format == 'md': f.write(f"# {data['title']}\n\n") f.write(f"> {data['meta_description']}\n\n") f.write(data['main_content']) return filename def main(): crawler = ProfessionalCrawler() while True: url = input("请输入要抓取的网址(输入q退出): ").strip() if url.lower() == 'q': break if not crawler.is_valid_url(url): print("无效的URL,请重新输入") continue if url in crawler.visited_urls: print("该网址已抓取过") continue print("开始抓取...") html = crawler.fetch_content(url) if html: data = crawler.parse_content(html, url) filename = crawler.save_data(data) print(f"抓取完成!数据已保存至: {filename}") crawler.visited_urls.add(url) else: print("抓取失败,请检查网址或网络连接") if __name__ == "__main__": main() ``` 三、功能亮点说明 1. 智能编码检测:自动识别网页编码,解决乱码问题 2. 内容提取优化: - 优先提取`<article>`标签内容 - 支持常见CMS的内容模式匹配 - 备用正文提取方案 3. 链接规范化处理:自动转换相对路径为绝对URL 4. 多格式存储支持:txt/markdown双格式输出 5. 御式编程设计: - 请求重试机制(3次) - 超时控制(10秒) - URL有效性验证 - 重复抓取 四、使用示例 ``` 请输入要抓取的网址(输入q退出): https://news.sina.com.cn 开始抓取... 抓取完成!数据已保存至: crawled_data_20231025_143856.txt ``` 五、专业建议 1. 遵守爬虫规范: - 检查`/robots.txt`(可添加自动解析功能) - 设置合理延时(建议添加`time.sleep(random.uniform(1,3))`) 2. 扩展建议: ```python # 在__init__中添加 self.delay = (1, 3) # 随机延时范围 self.proxies = {} # 代理配置 ``` 3. 法律合规:确保遵守目标网站的服务条款和相关法律法规 该框架已实现企业级爬虫的核心功能,可根据需求扩展以下功能: - 动态页面渲染(添加Selenium支持) - 数据清洗管道 - 分布式爬取 - 自动翻页机制 - 反反爬虫策略
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值