爬虫入门学习(八)模拟登录丁香园论坛爬取用户信息

爬虫入门学习(八)实战大项目模拟登录丁香园爬取信息

1 目标

模拟登录丁香园,并抓取页面所有人员的基本信息和回复贴子内容。

2 思路

  1. 模拟登录丁香园论坛
  2. 抓取评论和用户的个人主页链接
  3. 抓取用户个人主页信息
  4. 数据存储

3 主要的技术点

3.1 模拟登录

模拟登录元素定位基本问题不大。遇到的坑是【错误】Selenium报错:Element is not clickable at point(x, y)原因及解决办法汇总

3.2 抓取用户个人主页

我们需要先把用户个人主页网址抓出来,存为一个list,然后再依次抓取列表里面的每个网页,因为每个用户网页格式固定,所以可以实现一个循环进行批量抓取。
这里有个坑,荣誉版主的用户等级抓取跟其他的等级有所区别, 所以单独用了一个try…except来实现这方面的功能需求。

4 完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@author: Jock
"""

import time
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import requests
from lxml import etree
from copy import deepcopy

def login_dxy(url):
    # 声明浏览器对象
    driver = webdriver.Chrome()
    try:
        # 获取网页
        driver.get(url)
        # 最大化窗口
        driver.maximize_window()
        # 设置隐式等待
        driver.implicitly_wait(4)
        driver.find_element_by_link_text('登录').click()
        driver.find_element_by_link_text('返回电脑登录').click()
        driver.find_element_by_name('username').send_keys('帐号')   # 输入你的帐号
        driver.find_element_by_name('password').send_keys('密码')  # 输入你的密码
        driver.find_element_by_class_name('button').click()
        time.sleep(10)  # 留出10s手动处理验证码
        print("登录成功")
        # 抓取网页信息
        html = driver.page_source
        print(len(html))  # 测试爬取成功与否
        print(type(html))  # 测是抓取内容的类型
    except TimeoutException:
        print("Time out")
        print("登录失败!")
    except NoSuchElementException:
        print("No Element")
        print("登录失败!")
    if html:
        print("抓取成功!")
        driver.quit()
        return html
    else:
        print("抓取失败!")
        driver.quit()
        return None

def get_user_info(url):
    try:
        user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 \
        (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
        headers = {'User-Agent': user_agent}
        r = requests.get(url, headers=headers)  # 爬取完整的网页数据
        r.raise_for_status()  # 如果状态不是200,引发HTTPError异常
        info = []
        t = etree.HTML(r.text)
        # 提取用户名
        info.append(t.xpath('//div[@class="banner-inner__user-id pa"]/a/text()')[0])
        # 提取用户等级,这里有两种情况,所以用了一个try...except进行处理
        try:
            info.append(t.xpath('//div[@class="user-level-area"]/text()')[0])
        except:
            info.append(t.xpath('//span[@class="level-wrap__level-title mr15"]/text()')[0])
        # 提取用户关注数、粉丝数、丁当数
        info.extend(t.xpath('//div[@class="follows-fans clearfix"]/div/p/a/text()'))
        # 提取用户帖子数、精华数、积分数、得票数
        info.extend(t.xpath('//div[@class="main-nav-inner"]/ul/li/span[1]/text()'))
        print(info)
        return info
    except:
        print("访问出错")
        return ""  # 发生异常,返回空字符串


def extract_data(html):
    # 做好ElementTree
    tree = etree.HTML(html)
    # 列表ls_content存储发表内容
    ls_content = []
    # 以列表形式,返回所有包含发表内容的td标签
    ls = tree.xpath('//td[@class="postbody"]')
    length = len(ls)
    j = 0  # 记录抓取评论数
    for i in range(length):
        j += 1
        try:
            ls_content.append(''.join(ls[i].xpath('.//text()')).strip())  # 把每个td标签中的文本放入列表中
        except:
            print('抓取第{}评论出错'.format(j))
            continue
    # 获取用户个人主页网址,最后一个是抓取自己的
    ls_urls = tree.xpath('//div[@class="auth"]/a/@href')
    # 用于存储用户个人基本信息
    ls_user_info = []
    n = 0
    for url in ls_urls:
        n += 1
        print("现在开始抓取第{}位用户的主页:{}".format(n, url))
        info = get_user_info(str(url))
        ls_user_info.append(info)
    ls_total = list(zip(ls_user_info, ls_content))
    print(ls_total[0])
    print("恭喜你!成功抓取信息{}条!".format(len(ls_total)))
    return ls_total

def save_data(ls_total, fpath):
    n = 0
    with open(fpath, 'a', encoding='utf-8') as f:  # 以可读可写的权限打开文件
        for i in ls_total:
            n += 1
            try:
                print("现在开始写入第{}位用户的信息".format(n))
                p = deepcopy(i[0])
                p.append(i[1])
                print(p)  # 测试输出
                s = ','.join(p) + '\n'
                f.write(s)  # 写入数据
            except:
                print("警告!第{}条信息写入出错!".format(n))
                continue

def main():
    url = 'http://www.dxy.cn/bbs/thread/626626#626626'
    fpath = r'C:\Users\admin\Desktop\丁香园用户信息.csv'
    html = login_dxy(url)
    ls_total = extract_data(html)
    save_data(ls_total, fpath)
    print("成功结束程序!")
    
# 测试时间
def count_spend_time(func):
    start_time = time.perf_counter()
    func()
    end_time = time.perf_counter()
    time_dif = (end_time - start_time)
    second = time_dif%60
    minute = (time_dif//60)%60
    hour = (time_dif//60)//60
    print('spend ' + str(hour) + 'hours,' + str(minute) + 'minutes,' + str(second) + 'seconds')

if __name__ == '__main__':
    count_spend_time(main)

输出:

登录成功
343440
<class 'str'>
抓取成功!
现在开始抓取第1位用户的主页:http://i.dxy.cn/profile/楼医生
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1']
现在开始抓取第2位用户的主页:http://i.dxy.cn/profile/lion000
['lion000', '丁香园准中级站友', '1', '5', '82', '299', '0', '43', '7']
现在开始抓取第3位用户的主页:http://i.dxy.cn/profile/xghrh
['xghrh', '丁香园荣誉版主', '24', '35', '413', '4423', '4', '68', '15']
现在开始抓取第4位用户的主页:http://i.dxy.cn/profile/keys
['keys', '常驻站友', '3', '1', '141', '49', '0', '8', '0']
现在开始抓取第5位用户的主页:http://i.dxy.cn/profile/楼医生
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1']
现在开始抓取第6位用户的主页:http://i.dxy.cn/profile/shilly
['shilly', '丁香园中级站友', '34', '396', '362', '2643', '3', '244', '253']
现在开始抓取第7位用户的主页:http://i.dxy.cn/profile/jrhs
['jrhs', '丁香园准中级站友', '0', '15', '361', '1577', '1', '71', '45']
现在开始抓取第8位用户的主页:http://i.dxy.cn/profile/yangwein
['yangwein', '铁杆站友', '3', '1', '216', '123', '0', '26', '9']
现在开始抓取第9位用户的主页:http://i.dxy.cn/profile/duzl
['duzl', '铁杆站友', '1', '10', '107', '291', '0', '16', '2']
现在开始抓取第10位用户的主页:http://i.dxy.cn/profile/楼医生
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1']
现在开始抓取第11位用户的主页:http://i.dxy.cn/profile/jrhs
['jrhs', '丁香园准中级站友', '0', '15', '361', '1577', '1', '71', '45']
现在开始抓取第12位用户的主页:http://i.dxy.cn/profile/shanshoujie
['shanshoujie', '常驻站友', '2', '38', '11', '46', '0', '5', '13']
现在开始抓取第13位用户的主页:http://i.dxy.cn/profile/eabee
['eabee', '铁杆站友', '3', '2', '95', '83', '0', '14', '0']
现在开始抓取第14位用户的主页:http://i.dxy.cn/profile/xghrh
['xghrh', '丁香园荣誉版主', '24', '35', '413', '4423', '4', '68', '15']
现在开始抓取第15位用户的主页:http://i.dxy.cn/profile/楼医生
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1']
现在开始抓取第16位用户的主页:http://i.dxy.cn/profile/雨叶
['雨叶', '常驻站友', '3', '1', '115', '17', '0', '1', '1']
现在开始抓取第17位用户的主页:http://i.dxy.cn/profile/mmdra
['mmdra', '入门站友', '1', '3', '217', '52', '0', '0', '1']
现在开始抓取第18位用户的主页:http://i.dxy.cn/profile/daeik
['daeik', '常驻站友', '1', '65', '-60', '90', '0', '3', '51']
现在开始抓取第19位用户的主页:http://i.dxy.cn/profile/小贤
['小贤', '常驻站友', '19', '10', '27', '123', '0', '5', '5']
现在开始抓取第20位用户的主页:http://i.dxy.cn/profile/RonnieWhite
['RonnieWhite', '铁杆站友', '20', '29', '488', '151', '0', '24', '90']
现在开始抓取第21位用户的主页:http://i.dxy.cn/profile/shunwee
['shunwee', '常驻站友', '3', '0', '101', '29', '0', '2', '0']
现在开始抓取第22位用户的主页:http://i.dxy.cn/profile/Edmond
['Edmond', '铁杆站友', '0', '18', '107', '138', '0', '20', '15']
现在开始抓取第23位用户的主页:http://i.dxy.cn/profile/紫薇1219
['紫薇1219', '常驻站友', '3', '2', '115', '49', '0', '1', '1']
现在开始抓取第24位用户的主页:http://i.dxy.cn/profile/lingguang
['lingguang', '常驻站友', '3', '0', '115', '42', '0', '1', '6']
现在开始抓取第25位用户的主页:http://i.dxy.cn/profile/lingguang
['lingguang', '常驻站友', '3', '0', '115', '42', '0', '1', '6']
现在开始抓取第26位用户的主页:http://i.dxy.cn/profile/呆子
['呆子', '铁杆站友', '21', '12', '106', '88', '0', '11', '4']
现在开始抓取第27位用户的主页:http://i.dxy.cn/profile/lingguang
['lingguang', '常驻站友', '3', '0', '115', '42', '0', '1', '6']
现在开始抓取第28位用户的主页:http://i.dxy.cn/profile/dxy_6dsqhbmq
['dxy_6dsqhbmq', '入门站友', '3', '0', '0', '0', '0', '0', '0']
(['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1'], '我遇到一个“怪”病人,向大家请教。她,42岁。反复惊吓后晕厥30余年。每次受响声惊吓后发生跌倒,短暂意识丧失。无逆行性遗忘,无抽搐,无口吐白沫,无大小便失禁。多次跌倒致外伤。婴儿时有惊厥史。入院查体无殊。ECG、24小时动态心电图无殊;头颅MRI示小软化灶;脑电图无殊。入院后有数次类似发作。请问该患者该做何诊断,还需做什么检查,治疗方案怎样?')
恭喜你!成功抓取信息27条!
现在开始写入第1位用户的信息
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1', '我遇到一个“怪”病人,向大家请教。她,42岁。反复惊吓后晕厥30余年。每次受响声惊吓后发生跌倒,短暂意识丧失。无逆行性遗忘,无抽搐,无口吐白沫,无大小便失禁。多次跌倒致外伤。婴儿时有惊厥史。入院查体无殊。ECG、24小时动态心电图无殊;头颅MRI示小软化灶;脑电图无殊。入院后有数次类似发作。请问该患者该做何诊断,还需做什么检查,治疗方案怎样?']
现在开始写入第2位用户的信息
['lion000', '丁香园准中级站友', '1', '5', '82', '299', '0', '43', '7', '从发作的症状上比较符合血管迷走神经性晕厥,直立倾斜试验能协助诊断。在行直立倾斜实验前应该做常规的体格检查、ECG、UCG、holter和X-ray胸片除外器质性心脏病。贴一篇“口服氨酰心安和依那普利治疗血管迷走性晕厥的疗效观察”作者:林文华 任自文 丁燕生http://www.ccheart.com.cn/ccheart_site/Templates/jieru/200011/1-1.htm']
现在开始写入第3位用户的信息
['xghrh', '丁香园荣誉版主', '24', '35', '413', '4423', '4', '68', '15', '同意lion000版主的观点:如果此患者随着年龄的增长,其发作频率逐渐减少且更加支持,不知此患者有无这一特点。入院后的HOLTER及血压监测对此患者只能是一种安慰性的检查,因在这些检查过程中患者发病的机会不是太大,当然不排除正好发作的情况。对此患者应常规作直立倾斜试验,如果没有诱发出,再考虑有无可能是其他原因所致的意识障碍,如室性心动过速等,但这需要电生理尤其是心腔内电生理的检查,毕竟是有一种创伤性方法。因在外地,下面一篇文章可能对您有助,请您自己查找一下。心理应激事件诱发血管迷走性晕厥1例 ,杨峻青、吴沃栋、张瑞云,中国神经精神疾病杂志, 2002 Vol.28 No.2']
现在开始写入第4位用户的信息
['keys', '常驻站友', '3', '1', '141', '49', '0', '8', '0', '该例不排除精神因素导致的,因为每次均在受惊吓后出现。当然,在作出此诊断前,应完善相关检查,如头颅MIR(MRA),直立倾斜试验等。']
现在开始写入第5位用户的信息
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1', '谢谢上面几位的热心。这个病人从学会走路就出现症状,并且近几年发作越来越频繁,一个月有4、5次。如果说是血管迷走性晕厥,它的机理是什么?在这个病人身上如何解释?']
现在开始写入第6位用户的信息
['shilly', '丁香园中级站友', '34', '396', '362', '2643', '3', '244', '253', '不会是心因性癫痫吧?我不是专科,猜猜']
现在开始写入第7位用户的信息
['jrhs', '丁香园准中级站友', '0', '15', '361', '1577', '1', '71', '45', '倾斜试验一定先排除器质性心脏病。']
现在开始写入第8位用户的信息
['yangwein', '铁杆站友', '3', '1', '216', '123', '0', '26', '9', '1,头颅MRI示小软化灶;脑电图无殊,惊吓后晕厥30余年,婴儿时有惊厥史。先做动态脑电图排查癫痫,还有视觉诱发试验等,请神经内科会诊。2,排除神经内科问题后,行直立倾斜实验筛查血管迷走神经性晕厥。彩超排除器质性心脏病。']
现在开始写入第9位用户的信息
['duzl', '铁杆站友', '1', '10', '107', '291', '0', '16', '2', '楼医生 如果说是血管迷走性晕厥,它的机理是什么?体位改变-血液下移-Bp、HR下降-晕厥']
现在开始写入第10位用户的信息
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1', '该患者直立倾斜试验阴性。UCG无殊。实在是个棘手的病人。下步诊断、治疗方案如何,请各位同仁指点。谢谢!']
现在开始写入第11位用户的信息
['jrhs', '丁香园准中级站友', '0', '15', '361', '1577', '1', '71', '45', '动态脑电图就能排除癫痫吗?我看不能,发作时有脑电图吗?']
现在开始写入第12位用户的信息
['shanshoujie', '常驻站友', '2', '38', '11', '46', '0', '5', '13', '晕厥分类:心源性,非心源性,原因不明等三类,心源性包括心脏排血受阻,心律失常两类,非心源性包括血管神经运动失调性,脑血管疾病性,神经系统,代谢内分泌性等,所以常规检查包括心电图,超声心动图,CT,脑电图,24小时动态心电图,运动平板,心脏电生理等,但靠24小时动态心电图正常不能排除心律失常所致,必要时需要心电记录器延长监测,对于血管神经运动失调性及不明原因所致,建议行直立倾斜试验。']
现在开始写入第13位用户的信息
['eabee', '铁杆站友', '3', '2', '95', '83', '0', '14', '0', '问:这个病人智力有问题吗? 说她有30多年的发病史,多次发作时有外伤,问最严重的外伤情况如何?有无癔病的可能???说她婴儿时有惊厥史,说明她脑损伤病变的可能性存在,可能脑病变本身存在,也可能是惊厥后导致脑损伤。1)试用抗癫痫药物治疗,可以考虑用比较缓和的药物尝试。2)检测脑血管情况,实验用钙拮抗剂,或其他扩血管药物。']
现在开始写入第14位用户的信息
['xghrh', '丁香园荣誉版主', '24', '35', '413', '4423', '4', '68', '15', '希望下面的流程图对您的下步诊治有帮助。']
现在开始写入第15位用户的信息
['楼医生', '常驻站友', '2', '35', '168', '63', '0', '3', '1', '问:这个病人智力有问题吗? 说她有30多年的发病史,多次发作时有外伤,问最严重的外伤情况如何?有无癔病的可能???说她婴儿时有惊厥史,说明她脑损伤病变的可能性存在,可能脑病变本身存在,也可能是惊厥后导致脑损伤。1)试用抗癫痫药物治疗,可以考虑用比较缓和的药物尝试。2)检测脑血管情况,实验用钙拮抗剂,或其他扩血管药物。 该患者智力正常,已结婚生子。最严重的外伤是跌倒致脑出血,还有数次骨折、颜面部外伤,门牙跌落数枚。基本排除癔病可能。']
现在开始写入第16位用户的信息
['雨叶', '常驻站友', '3', '1', '115', '17', '0', '1', '1', '我认为这个病人可能是癫痫,应该发作时做脑电图']
现在开始写入第17位用户的信息
['mmdra', '入门站友', '1', '3', '217', '52', '0', '0', '1', 'Hehe!   LQTs!!!']
现在开始写入第18位用户的信息
['daeik', '常驻站友', '1', '65', '-60', '90', '0', '3', '51', '晕厥之前是否有出汗、恶心、脸色苍白等症状?晕厥持续时间?除考虑血管迷走性晕厥之外,癔病也不能除外。']
现在开始写入第19位用户的信息
['小贤', '常驻站友', '19', '10', '27', '123', '0', '5', '5', '每次晕厥后意识马上恢复,神志清楚,则考虑心血管原性可能大晕厥后意识恢复慢,有嗜睡,则中枢性可能大此患者意识恢复是否很快']
现在开始写入第20位用户的信息
['RonnieWhite', '铁杆站友', '20', '29', '488', '151', '0', '24', '90', 'LQT']
现在开始写入第21位用户的信息
['shunwee', '常驻站友', '3', '0', '101', '29', '0', '2', '0', '从病史看及发作情形看恶性心律失常所致晕厥可能性不大,鄙人认为不典型癫痫可能性较大,但也应排除迷走性晕厥,直立倾斜可以做但阳性并不能排除癫痫。可考虑用卡马西平试验性治疗。']
现在开始写入第22位用户的信息
['Edmond', '铁杆站友', '0', '18', '107', '138', '0', '20', '15', '楼医生 该患者直立倾斜试验阴性。UCG无殊。实在是个棘手的病人。下步诊断、治疗方案如何,请各位同仁指点。谢谢!楼医生,估计是查不出什么问题的,因为已经都快30多年的病史了,该有的疾病应该现出原形了,而现在却恰恰没法子找到它。既然都检查过了,也没发现有价值得的东西,而且每次发作多因惊吓引起,你看,是否就试一试“惊吓”的方法来诱发它呢?诱发的时候可以心电监护、血压监护、脑电图监测等等,相信肯定有所发现的。这也是不是办法的办法,您说呢?']
现在开始写入第23位用户的信息
['紫薇1219', '常驻站友', '3', '2', '115', '49', '0', '1', '1', '我认为癫痫的可能性最大,但的确应该先排除心源性的,可以进一步查一下。']
现在开始写入第24位用户的信息
['lingguang', '常驻站友', '3', '0', '115', '42', '0', '1', '6', '同志们呀,我认为是不是考虑一下先天性长QT综合征?这种病人可是会因为受惊吓导致晕厥甚至致死的呀!']
现在开始写入第25位用户的信息
['lingguang', '常驻站友', '3', '0', '115', '42', '0', '1', '6', '应当是一种肾上腺依赖性的,在受惊吓时肾上腺素大幅度升高,出现恶性心律失常而致晕厥。我不知道当时HOLTER检查时有没有发作?当时若有发作时的心电图最有说服力。我认为应当排除这方面的情况。必要的时候作惊吓试验,当然现场要有心电监护以及抢救措施。']
现在开始写入第26位用户的信息
['呆子', '铁杆站友', '21', '12', '106', '88', '0', '11', '4', '考虑为癫痫,建议动态脑电图,若阴性。则试用抗癫痫药']
现在开始写入第27位用户的信息
['lingguang', '常驻站友', '3', '0', '115', '42', '0', '1', '6', '应当做惊吓试验,脑电图与心电图同时监测。我想肯定会有结果的。无非是两种情况:脑源性与心源性。']
成功结束程序!
spend 0.0hours,2.0minutes,6.881398265000001seconds

5 项目后期拓展

爬取丁香园论坛上所有用户信息
思路

  1. 模拟登录丁香园论坛,选择一个大V(或者回复最多的贴子入手),爬取上面所有回复信息的用户主页url,作为初始的未访问UR集合L,采用set存储(直接去重。
  2. 调用ge_info()函数,一方面提取用户基本信息,另一方面,提取她关注的人的和关注她的人的主页URL。如果成功抓取这个用户基本信息(一个用户信息以一个元组的形式存储在集合中),则把该用户URL放入已访问集合(set),如果抓取失败,则把改URL放入访问失败url set。
  3. 对于抓取到的新的URL做如下处理:如果这个URL不在已访问的set中,则添加到未访问的URL set,如果访问过,则直接过滤掉。
  4. 不断的重复,直到没有数据可以抓取停止程序。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值