环境情况如下:
python-2.5.2
Python在文本处理方面很有特色,
用的时候书写自然,编写快速,处理速度也凑和。
下面是准备实现一个抓帖小工具,抓谁呢?
抓天涯吧,人气还行,只看楼主功能还收费。
python代码(CrawlerTianYa.py):
# coding:gbk
import os
import sys
import urllib
import sgmllib
escape_str = """!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~\t\r\n"""
class TitleCrawler(sgmllib.SGMLParser):
def __init__(self, url_str):
sgmllib.SGMLParser.__init__(self)
self.url_prefix = url_str.rsplit("/", 1)[0]
self.url_dict = {}
self.url_list = []
self.url_pre = None
def reset(self):
sgmllib.SGMLParser.reset(self)
self.writer_name = ""
self.writer_reach = False
self.topic_name = ""
self.topic_reach = False
self.vdata = []
def start_a(self, attrs):
for k, v in attrs:
if k != "href":
continue
if not self.writer_name and "Listwriter.asp?vwriter=" in v:
self.writer_reach = True
if "ArticlesList.asp?stritem=" in v:
self.topic_reach = True
self.vdata.append(self.vdata_temp)
if self.url_prefix in v and not self.url_dict.has_key(v):
self.url_pre = v
def start_br(self, attrs):
if self.topic_reach:
self.topic_reach = False
self.topic_name = escapeTxt("".join(self.vdata))
self.vdata = []
def handle_data(self, text):
self.vdata_temp = text
if self.writer_reach:
self.writer_reach = False
self.writer_name = text
if self.topic_reach:
self.vdata.append(text)
if self.url_pre:
text = text.strip()
if text.isdigit():
self.url_dict[self.url_pre] = text
self.url_list.append((self.url_pre, text))
self.url_pre = None
class UserCrawler(sgmllib.SGMLParser):
def __init__(self, writer):
sgmllib.SGMLParser.__init__(self)
self.writer_name = writer
self.is_all = (self.writer_name=="ALL")
def reset(self):
sgmllib.SGMLParser.reset(self)
self.writer_mayreach = False
self.writer_reach = False
self.topic_data = []
self.vdata = []
def start_a(self, attrs):
for k, v in attrs:
if k != "href":
continue
if "Listwriter.asp?vid=" in v or "Listwriter.asp?vwriter=" in v:
self.writer_mayreach = True
def start_table(self, attrs):
self.writer_mayreach = False
if self.writer_reach:
self.writer_reach = False
self.topic_data.extend(self.vdata)
self.vdata = []
def start_span(self, attrs):
self.writer_mayreach = False
if self.writer_reach:
self.writer_reach = False
self.topic_data.extend(self.vdata)
self.vdata = []
def start_br(self, attrs):
if self.writer_reach:
self.vdata.append("\n")
def handle_data(self, text):
if self.writer_mayreach:
self.writer_mayreach = False
if self.is_all or self.writer_name in text:
self.writer_reach = True
self.vdata.append(self.vdata_temp)
if self.writer_reach:
self.vdata.append(text)
self.vdata_temp = text
def recursive(url_str, url_tag, dir_str, topic_name, writer_name, url_dict, url_list):
# 递归最大页数判断:
page_count = int(url_dict["page_count"])
if page_count < 1:
return
url_dict[url_str] = url_tag
url_list.append((url_str, url_tag))
data_t = readUrl(url_str)
tc_t = TitleCrawler(url_str)
tc_t.feed(data_t)
tc_t.close()
if not topic_name:
topic_name = tc_t.topic_name
url_dict["topic_name"] = topic_name
if not writer_name:
writer_name = tc_t.writer_name
url_dict["writer_name"] = writer_name
if url_dict.has_key("user_name") and url_dict["user_name"]:
writer_name = url_dict["user_name"]
url_dict["writer_name"] = writer_name
if not dir_str:
dir_str = "tianya" + os.sep + topic_name
url_dict["dir_str"] = dir_str
if not os.path.exists(dir_str):
print dir_str
os.makedirs(dir_str)
uc_t = UserCrawler(writer_name)
uc_t.feed(data_t)
uc_t.close()
o_txt = "".join(uc_t.topic_data)
o_txt = stripTxt(o_txt)
file_name = dir_str + os.sep + url_tag + ".txt"
print file_name
file_cur = file(file_name, "w")
file_cur.write(o_txt)
file_cur.close()
# 递归最大页数判断:
page_count = int(url_dict["page_count"])
page_count = page_count - 1
url_dict["page_count"] = str(page_count)
if page_count < 1:
return
# 递归取下一个链接
for k, v in tc_t.url_list:
if not url_dict.has_key(k):
recursive(k, v, dir_str, topic_name, writer_name, url_dict, url_list)
def createUrlLog(dir_str, writer_name, url_list):
result = ["writer_name = %s"%writer_name]
for kv in url_list:
result.append("%s = %s"%kv)
file_name = dir_str + os.sep + "0.log"
print file_name
file_log = file(file_name, "w")
file_log.write("\n".join(result))
file_log.close()
def readUrl(url_str):
print url_str
socket_t = urllib.urlopen(url_str)
data_t = socket_t.read()
socket_t.close()
return data_t
def escapeTxt(text_str):
result = []
for i in text_str:
if i not in escape_str:
result.append(i)
return "".join(result)
def stripTxt(text_str):
text_arr = text_str.splitlines()
result = []
for i in text_arr:
line = i.replace(" ", " ")
result.append(line.strip())
return "\n".join(result)
def usage():
print "tianya -h"
print "tianya -c http://www.tianya.cn/publicforum/content/free/1/1491738.shtml"
print "tianya -a tianya/"
print "tianya -n 10 -c http://www.tianya.cn/publicforum/content/free/1/1491738.shtml"
print "tianya -n 10 -a tianya/『天涯杂谈』医行天下"
print " Options include:"
print " -h [help] - 打印帮助"
print " -c [create] - 从帖子首页开始抓取"
print " -a [append] - 更新已经抓取过的帖子"
print " -n [number] - 抓取的最大页面数,防止中途断掉,默认32页"
print " -u [user] - 抓取哪个用户的帖子,ALL代表全部,默认为楼主"
if not os.path.exists("tianya"):
return
tianya_dir = os.listdir("tianya")
if not tianya_dir:
return
print " 当前可更新:"
for i in tianya_dir:
print "tianya -a tianya/" + i
if __name__ == "__main__":
if "-h" in sys.argv:
usage()
elif "-c" in sys.argv:
page_count = "8"
if "-n" in sys.argv:
page_count = sys.argv[sys.argv.index("-n")+1]
user_name = ""
if "-u" in sys.argv:
user_name = sys.argv[sys.argv.index("-u")+1]
url_str = sys.argv[sys.argv.index("-c")+1]
url_dict = {"page_count":page_count, "user_name":user_name}
url_list = []
recursive(url_str, "1", None, None, None, url_dict, url_list)
createUrlLog(url_dict["dir_str"], url_dict["writer_name"], url_list)
elif "-a" in sys.argv:
page_count = "32"
if "-n" in sys.argv:
page_count = sys.argv[sys.argv.index("-n")+1]
user_name = ""
if "-u" in sys.argv:
user_name = sys.argv[sys.argv.index("-u")+1]
dir_str = sys.argv[sys.argv.index("-a")+1]
topic_name = dir_str.split(os.sep)[-1]
file_name = dir_str + os.sep + "0.log"
file_log = file(file_name, "r")
data_t = file_log.readlines()
file_log.close()
writer_name = None
url_str = None
url_tag = None
url_dict = {"page_count":str(int(page_count)+1), "user_name":user_name}
url_list = []
entry_t = data_t[0].split("=")
k = entry_t[0].strip()
v = entry_t[1].strip()
writer_name = v
for i in data_t[1:-1]:
entry_t = i.split("=")
k = entry_t[0].strip()
v = entry_t[1].strip()
url_dict[k] = v
url_list.append((k, v))
entry_t = data_t[-1].split("=")
k = entry_t[0].strip()
v = entry_t[1].strip()
url_str = k
url_tag = v
recursive(url_str, url_tag, dir_str, topic_name, writer_name, url_dict, url_list)
createUrlLog(dir_str, writer_name, url_list)
else:
usage()
具体使用方法如下:
把文件放入一个目录,如
D:\Spider
命令行进入目录,输入 tianya 回车,
一些常用命令行将打印出来,
例如 一个帖子第一页如下:
http://www.tianya.cn/publicforum/content/free/1/1491738.shtml
抓取命令使用:
tianya -c http://www.tianya.cn/publicforum/content/free/1/1491738.shtml
复杂点的可以用
tianya -c http://www.tianya.cn/publicforum/content/free/1/1491738.shtml -n 3
先抓3页下来看看。
曾经抓过的帖子,再次向后跟进就不需要这么多了,
现在可以再输入 tianya 回车,命令有增加了类似于:
tianya -a tianya/『天涯杂谈』医行天下
现在只要使用这个命令就能继续抓了。
网速不好的,可能会断线报错什么的,不过不用怕,再输入再抓即可。
更特殊的选项:
-n [number] - 抓取的最大页面数,防止中途断掉,默认32页
-u [user] - 抓取哪个用户的帖子,ALL代表全部,默认为楼主
这个-n是为网络状况不同的人而设置的,网络状况好的可以设置大点,网络状况不好就设置小一点。
-u 是为了专门查看某人的回帖而设置,当然不给这个参数默认就是楼主了,要是想把所有人都抓了呢(包括楼主和所有回帖),就这样:
tianya -c http://www.tianya.cn/publicforum/content/free/1/1491738.shtml -u ALL
tianya -a tianya/『天涯杂谈』医行天下 -u ALL
当初看孔二狗的东北往事:黑道风云20年没把我累死,
所以以后用工具,
希望大家在天涯看帖更轻松!(非广告)
分享到:
相关推荐
j2me学习笔记【2】——利用Display类的isColor()方法获取设备是否支持彩色的信息 j2me学习笔记【3】——简单的在线帮助示例 j2me学习笔记【4】——Item类的学习 j2me学习笔记【5】——抛出异常处理的小例子 j2me学习...
本压缩包包含的“C语言学习笔记”是一份详尽的C语言学习资料,旨在帮助读者深入理解和掌握C语言的基本概念、语法结构以及实际应用技巧。 一、C语言基础 C语言的基础包括变量、数据类型、运算符、流程控制等。变量...
《JSP & Servlet学习笔记(第2版)》涵盖了文本处理、图片验证、自动登录、验证过滤器、压缩处理、JSTL应用与操作等各种实用范例。 《JSP & Servlet学习笔记(第2版)》以“微博”项目贯穿全书,将JSP & Servlet技术应用...
这份"Linux学习笔记(强悍总结值得一看)"是Linux初学者的宝贵资源,也适合有经验的用户作为参考手册。以下是对笔记内容的详细概述: 1. **Linux常用命令**: Linux命令行是其强大的工具,掌握常用命令是Linux学习...
学习笔记通常包括了基础概念、关键特性、实用技巧以及常见问题的解决方法。 【标签】"h5"、"前端"、"学习笔记"进一步明确了内容的重点。"h5"即HTML5,是前端开发的核心;"前端"意味着这些笔记涉及的是用户可见和...
【Java学习笔记Markdown版】是针对Java初学者和进阶者的一份详尽教程,以Markdown格式编写,便于阅读和整理。Markdown是一种轻量级的标记语言,它允许用户使用易读易写的纯文本格式编写文档,然后转换成结构化的HTML...
Perl是一种强大的脚本编程语言,尤其适合文本处理和系统管理任务。在个人的学习过程中,掌握其基本语法和特性是至关重要的。以下是对标题和描述中提及的一些关键知识点的详细解释: 1. **操作符**: Perl中的`x`操作...
### Python学习笔记知识点详解 #### 一、Python简介与特性 **标题与描述解析:** "Python学习笔记.pdf" 的标题直接指出了文档的主题——Python的学习资料,而描述的重复表明该文档的主要内容即为Python的学习笔记...
这篇笔记将探讨如何使用HSQL处理文本数据库,结合标签"源码"和"工具",我们将深入理解HSQL的功能和应用。 首先,让我们了解HSQL的基本概念。HSQLDB是一个完全Java编写的数据库,这意味着它可以在任何支持Java的平台...
4. **字符串操作**:Python对字符串处理提供了丰富的函数,包括字符串连接、查找、替换、格式化输出等,了解正则表达式可以进行更复杂的文本处理。 5. **控制流**:通过if-elif-else语句进行条件判断,for和while...
本学习笔记涵盖了 web 前端开发的基础知识,包括 HTML 的基本结构、文档类型声明、常见的文本和列表标签、分区标签以及图片标签的使用方法。对于初学者而言,这些内容是构建网页的基础,而掌握这些基础知识是进一步...
【Java学习笔记模版】 Java实习工程师在学习过程中,会涉及到许多关键知识点,尤其是在企业级开发的场景下。从给出的四天学习笔记来看,实习生正在逐步掌握Java Web开发的基础和核心技能。以下是对这些知识点的详细...
这份"Python学习笔记"涵盖了从环境搭建到基础语法,再到数据类型和控制结构等关键知识点,旨在为初学者提供全面的学习指导。 首先,1.1章节介绍了Python的基础,包括Python的起源和历史。Python是由Guido van ...
2. **文本处理函数** - **LEFT**: 提取字符串左侧字符。`=LEFT("Hello", 2)` 返回 "He"。 - **RIGHT**: 提取字符串右侧字符。`=RIGHT("World", 3)` 返回 "rld"。 - **CONCATENATE**: 连接两个或更多文本字符串。`...
文档的更新历史表明,该学习笔记不断地被更新和完善,以确保其内容的准确性和时效性。作者黄海广对笔记进行了多次修改和补充,以修正错误并增加新的内容,比如OCTAVE操作内容、数学基础和公式推导等。这体现了作者对...
【Python学习笔记-王纯业】是一份专为Python初学者设计的教程,由王纯业编撰。这个教程深入浅出地介绍了Python编程的基础知识,帮助初学者快速上手。下面将详细阐述该教程中可能包含的重要知识点,以及Python入门者...
本书还涵盖了文本处理、图片验证、自动登录、验证过滤器、压缩处理、JSTL应用与操作等各种实用范例。 本书在讲解的过程中,以“微博”项目贯穿全书,随着每一章的讲述都在适当的时候将JSP & Servlet技术应用于...
在"java gui学习笔记"中,我们主要关注两个核心概念:组件(Components)和事件处理(Event Handling)。 首先,GUI界面设计通常涉及各种组件,如按钮(Buttons)、菜单项(MenuItems)、文本字段(TextFields)等...