使用selenium自动化爬取腾讯研究院报告

使用selenium自动化爬取腾讯研究院报告

需要用到的库:docx(需要pip install python-docx,不然有些函数无法使用)、re、requests、lxml、selenium、time、os等

项目实现难点:
1、报告标题存在非法字符无法保存,需使用re库中的replace函数进行替换;
2、报告需要存储图片,较为容易的txt写入方法无法满足需求,引入docx库进行存储;
3、在docx中只能添加本地已有图片,因此需要解析图片地址并提前存储图片,做if判断;
4、第一页标签中的next page按钮与第二页标签的next page按钮的存放位置不一样,需要先依次处理第一页、第二页后再进行迭代处理。

导入所需库

from selenium import webdriver
from lxml import etree
import time
import os
import re
import requests

import docx
# from docx import Document #另一种import方式
from docx.shared import RGBColor
from docx.shared import Inches #控制缩进
from docx.shared import Pt # 设置段落格式
from docx.enum.text import  WD_PARAGRAPH_ALIGNMENT  #WD_ALIGN_PARAGRAPH以前的库是这个已经废弃了,如果你遇到这种案例时建议替换为新的方法库  
from docx.oxml.ns import qn #设置字体格式

封装docx文件存储函数

def save_document(title,content,result):
    # 创建一个空白Word对象,并设置好字体
    file = docx.Document()
    file.styles['Normal'].font.name = u'仿宋'  # 可换成word里面任意字体
    file.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'仿宋') 

    # 创建一个封面 固定用法
    p = file.add_paragraph()  # 创建一个段落
    p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中设置
    p.paragraph_format.space_before = Pt(180)  # 段前距为180
    p.paragraph_format.space_after = Pt(30)  # 段后距为30
    run = p.add_run('腾讯研究院研究报告')  # 在段落里添加题目大标题
    font = run.font  # 设置字体
    font.color.rgb = RGBColor(54, 95, 145)  # 颜色设置,RGB颜色
    font.size = Pt(42)  # 字体大小设置,和word里面的字号相对应

    # 在封面上添加日期
    year = time.strftime("%Y")
    month = time.strftime("%m")
    day = time.strftime("%d")
    today = year + '年' + month + '月' + day + '日'  # 构造当天日期
    p = file.add_paragraph()  # 新建一个段落
    p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    run = p.add_run(today)  # 在段落中输入当天日期
    font = run.font
    font.color.rgb = RGBColor(54, 95, 145)
    font.size = Pt(26)

    # 添加分页符
    file.add_page_break()

    # 设置正文标题
#     p = file.add_paragraph()
#     p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 段落文字居中设置
#     run = p.add_run(title)
    run.font.color.rgb = RGBColor(54, 95, 145)  # 字体颜色设置
    run.font.size = Pt(22)  # 字体大小设置
    
    # 设置正文
    # 判断文档中是否有图片,图片是否与已有爬取图片匹配
    for i in range(1,len(content)+1):
        #找到当前文章所有图片地址,形成一个列表库
        imageurl = tree.xpath('/html/body/section/div/div[1]/div[2]//p/img/@src')
        #找到文章中每个P标签中的图片地址
        img = result.xpath('/html/body/section/div/div[1]/div[2]/p['+str(i)+']/img/@src')
        #将图片地址由列表转换为字符串,方便进行后续的if判断
        imgj = ''.join(img)
        #进行if判断,如果imgj存在于imageurl的列表中,则在word按顺序添加相应图片
        if imgj not in imageurl:
            pass
        else:
            # 根据本地图片名称,从本地添加图片
            file.add_picture('D:\\腾讯研究院\\图片库\\'+title+'\\'+imgj.split('/')[-1], width=Pt(400))
        # 判断文章内容是否存在,存在则按顺序添加    
        content1 = result.xpath('/html/body/section/div/div[1]/div[2]/p['+str(i)+']//text()')
        if content1 is None:
            pass
        else:
            p = file.add_paragraph()
            p.paragraph_format.first_line_indent = Inches(0.2)# 这个控制首行缩进
            run.font.size = Pt(16)
            content1j = ''.join(content1)
            run=p.add_run(content1j)
    
    f = "D:\腾讯研究院\\"
    if not os.path.exists(f):
        os.makedirs(f)
        print("文件不存在,创建")
        
    # 把Word文档保存,注意需提前创建好保存文件夹
    file.save(f+str(title)+'.docx')
    print('报告生成完毕')

使用selenium执行自动化爬虫

url = ['https://www.tisi.org/?cat=2&page=1','https://www.tisi.org/?cat=2&page=2']
page_text_list = []
#由于“下一页”按钮位置在第一页和第二页有所区别,因此解析第一页及第二页的文章内容,后续按照网页格式进行爬取
for u in url:
    bro = webdriver.Chrome(executable_path='./chromedriver')
    bro.get(u)
    # page_text_list = []
    time.sleep(2)
    page_text = bro.page_source #当前页面全部加载完毕后对应的所有数据
    page_text_list.append(page_text)

#点击下一页(实际上是第三页)
for i in range(2):
    next_page = bro.find_element_by_xpath('/html/body/section/div/div[12]/ul/li[8]/a')
    next_page.click()
    time.sleep(1)
    page_text_list.append(bro.page_source)

#创建报告的存储文件夹
file = "D:\\腾讯研究院\\"
if not os.path.exists(file):
    os.makedirs(file)
    print("文件夹不存在,创建")
    
#创建报告图片的总存储文件夹   
file1 = "D:\\腾讯研究院\\图片库\\"
if not os.path.exists(file1):
    os.makedirs(file1)
    print("文件夹不存在,创建")


#解析每篇文章的地址并将地址所有的文字存储到docx文件中
for page_text in page_text_list:
    tree = etree.HTML(page_text)
    cont_list = tree.xpath('/html/body/section/div')
    for cont in cont_list:
        title = cont.xpath('//*[@class="new-article-title"]//text()')
        content = cont.xpath('//*[@class="new-article-title"]/a/@href')
        #在首页解析每篇文章的地址
        for c in content:
            cc = "https:"+c
            bro.get(cc)
            page_content = bro.page_source
            tree = etree.HTML(page_content)
            
            #解析文章标题
            atitle = tree.xpath('/html/body/section/div/div[1]/p//text()')
            
            #格式化标题
            wanzheng1 = ''.join(atitle)
            wanzheng12 = re.sub('[\/::*?"<>|]','-',wanzheng1)
            
            #解析网页p标签,获取P标签列表
            acontent = tree.xpath('/html/body/section/div/div[1]/div[2]/p')
            
            #按照报告对爬取图片进行分类
            file2 = "D:\\腾讯研究院\\图片库\\"+wanzheng12+"\\"
            if not os.path.exists(file2):
                os.makedirs(file2)
                print("文件不存在,创建")
            imageurl = tree.xpath('/html/body/section/div/div[1]/div[2]//p/img/@src')
            for iu in imageurl:
                response = requests.get(iu)
                result = response.content
                f=open('D:\\腾讯研究院\\图片库\\'+wanzheng12+"\\"+iu.split('/')[-1],'wb')
                f.write(result)
                f.close()
            save_document(wanzheng12,acontent,tree)

time.sleep(2)
bro.quit()
print('爬取成功')

总结:
1、selenium效率太低;
2、内部迭代次数太多,时间复杂度成倍增加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值