爬虫

import requests
from bs4 import BeautifulSoup
from urllib.parse import urlparse
from urllib.parse import parse_qs
import sys
import json
# 引入库

# 第一步 给定网址看否能够链接
def get_url_content(url):
    response = requests.get(url)
    # 请求访问网站
    if response.status_code == 200:
        # 判断网站状态(返回200极正常)
        if "抱歉,指定的主题不存在或已被删除或正在被审核" in response.text:
            return False
        else:
            return response.text
    else:
        return False
        # 判断是否返回‘抱歉’,是返回false,否返回网页源码

#解析发帖数据
def parse_post_data(html_text):
    soup_object = BeautifulSoup(html_text,"html.parser")
    # 解析网页源码
    title = soup_object.title.string
    # 获取title并转换成string类型
    url = soup_object.link['href']
    # 获取href后的链接里的内容
    parsed_url = urlparse(url)
    # 将url解析成6部分(协议、位置,路径,参数,查询,片段)
    query_string_object = parse_qs(parsed_url.query)
    # 获取解析后元组中的query
    tid = query_string_object['tid'][0]
    # 获取解析后元组中第一个tid,代表发帖
    user_list = get_post_userlist(soup_object)
    # 调用第四个函数get_post_userlist对网页源码进行处理
    content_list = get_post_content_list(soup_object)
    # 调用第三个函数et_post_content_list对网页源码进行处理
    for i in range(len(content_list)):
        content_list[i]["user_info"] = user_list[i]
        # 获取发帖用户
    post_content_info = {
        "title": title,
        "url":url,
        "tid":tid,
        "author":user_list[0],
        "content":content_list[0]["content"],
        "comments":content_list[1:]
    }

    # print("tid:%s"%(tid),end="")
    # print("\ttitle:%s"%(title),end="")
    # print("\turl:%s"%(url))
    # print("\tauthor:%s"%(user_list[0]['user_name']),end="")
    # print("\tauthor_uid:%s"%(user_list[0]['uid']),end="")
    # print("\tcontent:%s"%(content_list[0]["content"]),end="")
    # #print("----------------content:%s" % (content_list[0]))
    # #print("------------comments:%s"%content_list[0]["user_info"]['user_name'])
    # #print("------------comments_uid:%s"%content_list[0]["user_info"]['uid'])
    # #if len(content_list)>0:
    #     #for i in range(0,len(content_list)):
    # print("\tcomments_tid:%s"%content_list[0]['tid'],end="")
    # print("\tcomments_content:%s"%content_list[0]['content'],end="")
    # print("\tuserinfo_user_name:%s"%content_list[0]['user_info']['user_name'],end="")
    # print("\tuserinfo_user_uid:%s"%content_list[0]['user_info']['uid'],end="")

    return post_content_info
    # 将抓取的数据以字典形式保存

#解析发帖的内容列表    返回值<class 'list'>: [{'tid': '2', 'content': '\r\n我觉得是帖帖不休~'}]
def get_post_content_list(post_soup_object):

    content_object_list = post_soup_object.select('.t_f')
    # 选择器。源码中标有.t_f的为获取对象
    content_list = []
    # 定义一个帖子内容空列表
    for i in range(len(content_object_list)):
        postmessage_id = content_object_list[i]['id']
        # 获取发帖id
        tid = postmessage_id.split("_")[1]
        # 获取发帖id,以_进行切分,取第二个元素
        content = content_object_list[i].string
        # 将下角标为i的数据转换为string类型
        content_list.append({"tid":tid,"content":content})
    return content_list
    # 返回帖子内容列表
# 解析全部网页方法返回值是<class 'list'>: [{'user_name': 'csbNG3M', 'uid': '3'}]
def get_post_userlist(post_soup_object):
    user_info_doms = post_soup_object.select(".authi")
    # 选择器,可以获得多条也可以获得单条数据
    user_list = []
    # 定义一个用户空列表
    for i in range(len(user_info_doms)):
        if i%2 == 0:
            user_name = user_info_doms[i].a.string
            # 将下角标为i的数据转换成string类型
            uid = parse_qs(user_info_doms[i].a['href'])['uid'][0]
            user_list.append({"user_name":user_name,"uid":uid})
            # 向列表中添加元素
    return user_list
    # 返回发帖者的数组

def write_to_file(content):
    with open("test.txt",'a',encoding="utf-8") as f:
        f.write((content["url"])+"\t\t\t")
        f.write((content["tid"])+"\t\t\t")
        f.write((content["author"]["user_name"]) + "\t\t\t")
        f.write((content["author"]["uid"]) + "\t\t\t")
        # if 0==len(content["comments"]):
        #     content["comments"]=null
        f.write(json.dumps(content["comments"],ensure_ascii=False)+ "\t\t\t")
        f.write('{0:<30}'.format((content["title"])).split('-')[0]+"\n")

# 调用get_url_content方法请求网页,并以文本形式返回网页源码http://114.112.74.138/forum.php?mod=forumdisplay&fid=2
content = get_url_content("http://114.112.74.138/forum.php?mod=viewthread&tid=2")
parsed_post_content_info = parse_post_data(content)
# 调用parsed_post_data方法
# max_tid = sys.argv[1]
# sys.argv实现从程序外部向程序传递参数
post_base_url="http://114.112.74.138//forum.php?mod=viewthread&tid="
for i in range(int(1000)):
    ret = get_url_content(post_base_url+str(i))
    # 调用get_url_content方法请求目标网站
    if ret != False:
        parsed_post_data = parse_post_data(ret)
        print("got post data,tid:%s" % (parsed_post_data["tid"]))
        # #{'title': '什么发帖软件最好? - 默认版块 -  Discuz! Board -  Powered by Discuz!',
        #  'url': 'http://114.112.74.138/forum.php?mod=viewthread&tid=1', 'tid': '1',
        #  'author': {'user_name': 'cs4bxCo', 'uid': '2'}, 'content': '\r\n我觉得是帖帖不休~', 'comments': []}
        write_to_file(parsed_post_data)
    else:
        print("tid:%s not found,continue" % (i))
        # 判断ret是否不等于false


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值