爬虫之天涯论坛

来源:互联网 发布:人工智能与智慧城市 编辑:程序博客网 时间:2024/05/16 01:12

爬虫之天涯论坛

需求

获取天涯论坛上某个关键字搜索出来的所有页面里面的每个帖子的楼主ID和回帖者的ID

解决方法

Python+正则表达式

re.findall(pattern, string[, flags])
搜索string,以列表形式返回全部能匹配的子串。

str.find(str, beg=0, end=len(string))
如果包含子字符串返回开始的索引值,否则返回-1

import requestsimport reimport time# create time: 20170721# language: python3.4# 打开保存到本地文件with open('.\data\data20170803.txt','w') as file:    # 爬取的页码范围    for page in range(75):        # 拼凑出某一页的URL        url = 'http://search.tianya.cn/bbs?q=粮食&pn=' + str(page + 1)        # 获取某一面的内容        content = requests.get(url).content.decode('utf-8')        # 定位到需要的一块区域        start = content.find(r'<div class="searchListOne">')        end = content.find(r'<li id=search_msg style="display:none"></li>')        # 把需要的区域从整体切割出来        content = content[start: end]        # 使用正则表达式匹配出所有帖子的URL存入一个列表        result = re.findall(r'<h3><a.href="([\s\S]{0,100})" target="_blank".>', content, re.S)        # print(result)        # 进入某一个帖子        for link in result:            # 获取某一个帖子页面的内容            content = requests.get(link).content.decode('utf-8')            # 对帖子内容选取需要的区域            start = content.find(r'<div class="atl-info">')            end = content.find(r'<div class="mb15 cf">')            # 把需要的区域从帖子所有内容中提取出来            contents = content[start: end]            # 使用正则表达式 匹配楼主ID            uid = re.findall(r'<span>楼主:<a href=".{0,30}" target="_blank" class="js-vip-check" uid="(\d+)" uname=',contents,re.S)            # print(uid, '----------------------------------')            # 对帖子内容选取需要的区域            start = content.find(r'<div class="atl-main">')            end = content.find(r'<div class="clearfix">')            # 把需要的区域从帖子所有内容中提取出来            contents = content[start: end]            # 使用正则表达式 匹配回帖者ID            fuid = re.findall(r'<div class="atl-item" _host=".{0,20}" id="\d+" replyid="\d+" _hostid="(\d+)" js_username=',contents, re.S)            # 判断是否为楼主自己            if len(uid) and fuid :                # 不是楼主则把(楼主ID\t回帖者ID)写入文件                for i in fuid:                    if uid[0] != i:                        file.write(uid[0] + '\t' + i + '\n')            # 对帖子内容选取需要的区域            start = content.find(r'<div class="atl-pages">')            end = content.find(r'<div class="atl-pages host-pages"></div>')            # 把需要的区域从帖子所有内容中提取出来            contents = content[start: end]            # 获取回复内容的下一页的URL            linkto = re.findall(r'<a href="(.{0,50})" class="js-keyboard-next">下页</a>', contents, re.S)            # 如果有下一页            while len(linkto):                # 由于获取到的是相对地址,需要进行拼凑                urllink = 'http://bbs.tianya.cn' + linkto[0]                # 获取某一面的内容                content = requests.get(urllink).content.decode('utf-8')                # 对帖子内容选取需要的区域                start = content.find(r'<div class="atl-main">')                end = content.find(r'<div class="clearfix">')                # 把需要的区域从帖子所有内容中提取出来                contents = content[start: end]                # 使用正则表达式 匹配回帖者ID                fuid = re.findall(                    r'<div class="atl-item" _host=".{0,20}" id="\d+" replyid="\d+" _hostid="(\d+)" js_username=', contents,                    re.S)                # 判断是否为楼主自己                if len(uid) and fuid:                    # 不是楼主则把(楼主ID\t回帖者ID)写入文件                    for i in fuid:                        if uid[0] != i:                            file.write(uid[0] + '\t' + i + '\n')                # 对帖子内容选取需要的区域                start = content.find(r'<div class="atl-pages">')                end = content.find(r'<div class="atl-pages host-pages"></div>')                # 把需要的区域从帖子所有内容中提取出来                contents = content[start: end]                # 获取回复内容的下一页的URL                linkto = re.findall(r'<a href="(.{0,50})" class="js-keyboard-next">下页</a>', contents, re.S)#输出进程到此运行的时间print(time.clock())

结果

这里写图片描述

优化方案

使用多线程

原创粉丝点击