Github上的百度文库爬虫代码,拷贝下来学习

电脑技术 电脑技术 922 人阅读 | 2 人回复 | 2022-04-06

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import os
  2. import time

  3. from selenium import webdriver
  4. from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
  5. from scrapy import Selector
  6. import requests
  7. from my_fake_useragent import UserAgent
  8. import docx
  9. from docx.shared import Inches
  10. import cv2
  11. from pptx import Presentation
  12. from pptx.util import Inches

  13. #dows是的chromedriver
  14. chromedriver_path = "./chromedriver.exe"
  15. #用ubuntu的chromedriver
  16. # chromedriver_path = "./chromedriver"

  17. doc_dir_path = "./doc"
  18. ppt_dir_path = "./ppt"
  19. # url = "https://wenku.baidu.com/view/4410199cb0717fd5370cdc2e.html?fr=search"# doc_txt p
  20. # url = "https://wenku.baidu.com/view/4d18916f7c21af45b307e87101f69e314332fa36.html" # doc_txt span
  21. # url = "https://wenku.baidu.com/view/dea519c7e53a580216fcfefa.html?fr=search" # doc_txt span br
  22. # url = 'https://wk.baidu.com/view/062edabeb6360b4c2e3f5727a5e9856a5712262d?pcf=2&bfetype=new' # doc_img
  23. # url = "https://wenku.baidu.com/view/2af6de34a7e9856a561252d380eb6294dd88228d"# vip限定doc
  24. # url = "https://wenku.baidu.com/view/3de365cc6aec0975f46527d3240c844769eaa0aa.html?fr=search" #ppt
  25. # url = "https://wenku.baidu.com/view/18a8bc08094e767f5acfa1c7aa00b52acec79c55"#pdf
  26. # url = "https://wenku.baidu.com/view/bbe27bf21b5f312b3169a45177232f60dccce772"
  27. # url = "https://wenku.baidu.com/view/5cb11d096e1aff00bed5b9f3f90f76c660374c24.html?fr=search"
  28. # url = "https://wenku.baidu.com/view/71f9818fef06eff9aef8941ea76e58fafab045a6.html"
  29. # url = "https://wenku.baidu.com/view/ffc6b32a68eae009581b6bd97f1922791788be69.html"
  30. url = "https://wenku.baidu.com/view/d4d2e1e3122de2bd960590c69ec3d5bbfd0adaa6.html"

  31. class DownloadImg():
  32.     def __init__(self):
  33.         self.ua = UserAgent()

  34.     def download_one_img(self, img_url, saved_path):
  35.         # 下载图片
  36.         header = {
  37.             "User-Agent": "{}".format(self.ua.random().strip()),
  38.             'Connection': 'close'}
  39.         r = requests.get(img_url, headers=header, stream=True)
  40.         print("请求图片状态码 {}".format(r.status_code))  # 返回状态码
  41.         if r.status_code == 200:  # 写入图片
  42.             with open(saved_path, mode="wb") as f:
  43.                 f.write(r.content)
  44.             print("download {} success!".format(saved_path))
  45.         del r
  46.         return saved_path


  47. class StartChrome():
  48.     def __init__(self):
  49.         mobile_emulation = {"deviceName": "Galaxy S5"}
  50.         capabilities = DesiredCapabilities.CHROME
  51.         capabilities['loggingPrefs'] = {'browser': 'ALL'}
  52.         options = webdriver.ChromeOptions()
  53.         options.add_experimental_option("mobileEmulation", mobile_emulation)
  54.         self.brower = webdriver.Chrome(executable_path=chromedriver_path, desired_capabilities=capabilities,
  55.                                        chrome_options=options)
  56.         # 启动浏览器,打开需要下载的网页
  57.         self.brower.get(url)
  58.         self.download_img = DownloadImg()

  59.     def click_ele(self, click_xpath):
  60.         # 单击指定控件
  61.         click_ele = self.brower.find_elements_by_xpath(click_xpath)
  62.         if click_ele:
  63.             click_ele[0].location_once_scrolled_into_view  # 滚动到控件位置
  64.             self.brower.execute_script('arguments[0].click()', click_ele[0])  # 单击控件,即使控件被遮挡,同样可以单击

  65.     def judge_doc(self, contents):
  66.         # 判断文档类别
  67.         p_list = ''.join(contents.xpath("./text()").extract())
  68.         span_list = ''.join(contents.xpath("./span/text()").extract())
  69.         # # if span_list
  70.         # if len(span_list)>len(p_list):
  71.         #     xpath_content_one = "./br/text()|./span/text()|./text()"
  72.         # elif len(span_list)<len(p_list):
  73.         #     # xpath_content_one = "./br/text()|./text()"
  74.         #     xpath_content_one = "./br/text()|./span/text()|./text()"
  75.         if len(span_list)!=len(p_list):
  76.             xpath_content_one = "./br/text()|./span/text()|./text()"
  77.         else:
  78.             xpath_content_one = "./span/img/@src"
  79.         return xpath_content_one

  80.     def create_ppt_doc(self, ppt_dir_path, doc_dir_path):
  81.         # 点击关闭开通会员按钮
  82.         xpath_close_button = "//div[@class='na-dialog-wrap show']/div/div/div[@class='btn-close']"
  83.         self.click_ele(xpath_close_button)
  84.         # 点击继续阅读
  85.         xpath_continue_read_button = "//div[@class='foldpagewg-icon']"
  86.         self.click_ele(xpath_continue_read_button)
  87.         # 点击取消打开百度app按钮
  88.         xpath_next_content_button = "//div[@class='btn-wrap']/div[@class='btn-cancel']"
  89.         self.click_ele(xpath_next_content_button)
  90.         # 循环点击加载更多按钮,直到显示全文
  91.         click_count = 0
  92.         while True:
  93.             # 如果到了最后一页就跳出循环
  94.             if self.brower.find_elements_by_xpath("//div[@class='pagerwg-loadSucc hide']") or self.brower.find_elements_by_xpath("//div[@class='pagerwg-button' and @style='display: none;']"):
  95.                 break
  96.             # 点击加载更多
  97.             xpath_loading_more_button = "//span[@class='pagerwg-arrow-lower']"
  98.             self.click_ele(xpath_loading_more_button)
  99.             click_count += 1
  100.             print("第{}次点击加载更多!".format(click_count))
  101.             # 等待一秒,等浏览器加载
  102.             time.sleep(1.5)

  103.         # 获取html内容
  104.         sel = Selector(text=self.brower.page_source)
  105.         #判断文档类型
  106.         xpath_content = "//div[@class='content singlePage wk-container']/div/p/img/@data-loading-src|//div[@class='content singlePage wk-container']/div/p/img/@data-src"
  107.         contents = sel.xpath(xpath_content).extract()
  108.         if contents:#如果是ppt
  109.             self.create_ppt(ppt_dir_path, sel)
  110.         else:#如果是doc
  111.             self.create_doc(doc_dir_path, sel)
  112.         # a = 3333
  113.         # return sel

  114.     def create_ppt(self, ppt_dir_path, sel):
  115.         # 如果文件夹不存在就创建一个
  116.         if not os.path.exists(ppt_dir_path):
  117.             os.makedirs(ppt_dir_path)

  118.         SLD_LAYOUT_TITLE_AND_CONTENT = 6  # 6代表ppt模版为空
  119.         prs = Presentation()  # 实例化ppt

  120.         # # 获取完整html
  121.         # sel = self.get_html_data()
  122.         # 获取标题
  123.         xpath_title = "//div[@class='doc-title']/text()"
  124.         title = "".join(sel.xpath(xpath_title).extract()).strip()
  125.         # 获取内容
  126.         xpath_content_p = "//div[@class='content singlePage wk-container']/div/p/img"
  127.         xpath_content_p_list = sel.xpath(xpath_content_p)
  128.         xpath_content_p_url_list=[]
  129.         for imgs in xpath_content_p_list:
  130.             xpath_content = "./@data-loading-src|./@data-src|./@src"
  131.             contents_list = imgs.xpath(xpath_content).extract()
  132.             xpath_content_p_url_list.append(contents_list)

  133.         img_path_list = []  # 保存下载的图片路径,方便后续图片插入ppt和删除图片
  134.         # 下载图片到指定目录
  135.         for index, content_img_p in enumerate(xpath_content_p_url_list):
  136.             p_img_path_list=[]
  137.             for index_1,img_one in enumerate(content_img_p):
  138.                 one_img_saved_path = os.path.join(ppt_dir_path, "{}_{}.jpg".format(index,index_1))
  139.                 self.download_img.download_one_img(img_one, one_img_saved_path)
  140.                 p_img_path_list.append(one_img_saved_path)

  141.             p_img_max_shape = 0
  142.             for index,p_img_path in enumerate(p_img_path_list):
  143.                 img_shape = cv2.imread(p_img_path).shape
  144.                 if p_img_max_shape<img_shape[0]:
  145.                     p_img_max_shape = img_shape[0]
  146.                     index_max_img = index
  147.             img_path_list.append(p_img_path_list[index_max_img])


  148.         print(img_path_list)
  149.         # 获取下载的图片中最大的图片的尺寸
  150.         img_shape_max=[0,0]
  151.         for img_path_one in img_path_list:
  152.             img_path_one_shape = cv2.imread(img_path_one).shape
  153.             if img_path_one_shape[0]>img_shape_max[0]:
  154.                 img_shape_max = img_path_one_shape
  155.         # 把图片统一缩放最大的尺寸
  156.         for img_path_one in img_path_list:
  157.             cv2.imwrite(img_path_one,cv2.resize(cv2.imread(img_path_one),(img_shape_max[1],img_shape_max[0])))
  158.         # img_shape_path = img_path_list[0]
  159.         # 获得图片的尺寸
  160.         # img_shape = cv2.imread(img_shape_path).shape
  161.         # 把像素转换为ppt中的长度单位emu,默认dpi是720
  162.         # 1厘米=28.346像素=360000
  163.         # 1像素 = 12700emu
  164.         prs.slide_width = img_shape_max[1] * 12700  # 换算单位
  165.         prs.slide_height = img_shape_max[0] * 12700

  166.         for img_path_one in img_path_list:
  167.             left = Inches(0)
  168.             right = Inches(0)
  169.             # width = Inches(1)
  170.             slide_layout = prs.slide_layouts[SLD_LAYOUT_TITLE_AND_CONTENT]
  171.             slide = prs.slides.add_slide(slide_layout)
  172.             pic = slide.shapes.add_picture(img_path_one, left, right, )
  173.             print("insert {} into pptx success!".format(img_path_one))
  174.             # os.remove(img_path_one)

  175.         for root,dirs,files in os.walk(ppt_dir_path):
  176.             for file in files:
  177.                 if file.endswith(".jpg"):
  178.                     img_path = os.path.join(root,file)
  179.                     os.remove(img_path)

  180.         prs.save(os.path.join(ppt_dir_path, title + ".pptx"))
  181.         print("download {} success!".format(os.path.join(ppt_dir_path, title + ".pptx")))

  182.     def create_doc(self, doc_dir_path, sel):
  183.         # 如果文件夹不存在就创建一个
  184.         if not os.path.exists(doc_dir_path):
  185.             os.makedirs(doc_dir_path)
  186.         # # 获取完整html
  187.         # sel = self.get_html_data()
  188.         # 获取标题
  189.         xpath_title = "//div[@class='doc-title']/text()"
  190.         title = "".join(sel.xpath(xpath_title).extract()).strip()

  191.         document = docx.Document()  # 创建word文档
  192.         document.add_heading(title, 0)  # 添加标题

  193.         # 获取文章内容
  194.         xpath_content = "//div[contains(@data-id,'div_class_')]//p"
  195.         # xpath_content = "//div[contains(@data-id,'div_class_')]/p"
  196.         contents = sel.xpath(xpath_content)
  197.         # 判断内容类别
  198.         xpath_content_one = self.judge_doc(contents)
  199.         if xpath_content_one.endswith("text()"):  # 如果是文字就直接爬
  200.             for content_one in contents:
  201.                 one_p_list = content_one.xpath(xpath_content_one).extract()
  202.                 p_txt = ""
  203.                 for p in one_p_list:
  204.                     if p==" ":
  205.                         p_txt += ('\n'+p)
  206.                     else:
  207.                         p_txt += p
  208.                 # content_txt_one = '*'.join(content_one.xpath(xpath_content_one).extract())
  209.                 pp = document.add_paragraph(p_txt)
  210.             document.save(os.path.join(doc_dir_path, '{}.docx'.format(title)))
  211.             print("download {} success!".format(title))
  212.         elif xpath_content_one.endswith("@src"):  # 如果是图片就下载图片
  213.             for index, content_one in enumerate(contents.xpath(xpath_content_one).extract()):
  214.                 # 获取图片下载路径
  215.                 content_img_one_url = 'https:' + content_one
  216.                 # 保存图片
  217.                 saved_image_path = self.download_img.download_one_img(content_img_one_url, os.path.join(doc_dir_path,
  218.                                                                                                         "{}.jpg".format(
  219.                                                                                                             index)))
  220.                 document.add_picture(saved_image_path, width=Inches(6))  # 在文档中加入图片
  221.                 os.remove(saved_image_path)  # 删除下载的图片
  222.             document.save(os.path.join(doc_dir_path, '{}.docx'.format(title)))  # 保存文档到指定位置
  223.             print("download {} success!".format(title))


  224. if __name__ == "__main__":
  225.     start_chrome = StartChrome()
  226.     # start_chrome.create_doc_txt(doc_dir_path)
  227.     start_chrome.create_ppt_doc(ppt_dir_path, doc_dir_path)
复制代码


回答|共 2 个

Starrry 发表于 2022-4-6 23:01:31| 字数 20 来自手机 | 显示全部楼层

大概看完了代码,很棒,要爬虫得做足功夫。

willsonlincake 发表于 2022-4-6 23:05:07| 字数 78 来自手机 | 显示全部楼层

Starrry 发表于 2022-4-6 23:01
大概看完了代码,很棒,要爬虫得做足功夫。

我也觉得,虽然还暂时不能实现下载ppt格式,不过这个代码对我研究很有用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则