Python爬虫 selenium自动化 利用搜狗搜索爬取微信公众号文章信息

少年最好的地方就是:虽然嘴上说要放弃,心底却总会憋着一口气。——刘同

一、需求和网页分析

URL:https://weixin.sogou.com/

你是否有特别喜欢的一些公众号文章,比如说关于网易云热评的。

我那么多遗憾,那么多期盼,你知道吗

下面以在搜狗里搜索 网易云热评墙 为例,爬取得到的全部文章信息(包括标题、日期、链接),并保存到Excel,使用Selenium来实现。
在这里插入图片描述
在这里插入图片描述
找到搜索框和搜文章按钮的位置

在这里插入图片描述
找到想要爬取的数据

在这里插入图片描述
10页之后的内容,要扫码登录才能继续获取。

二、selenium爬虫

  • selenium是一个用于web应用程序自动化测试的工具,直接运行在浏览器当中,可以通过代码控制与页面上元素进行交互,并获取对应的信息。
  • selenium很大的一个优点是:不需要复杂地构造请求,访问参数跟使用浏览器的正常用户一模一样,访问行为也相对更像正常用户,不容易被反爬虫策略命中,容易实现所见即所得。
  • selenium的缺点:操作均需要等待页面加载完毕后才可以继续进行,所以速度要慢,效率不高。

代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
import time
import datetime
import logging
import random
import openpyxl


logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')
wb = openpyxl.Workbook()
sheet = wb.active
sheet.append(['num', 'title', 'date', 'link'])
# 配置chromedriver
chrome_driver = r'D:\python\pycharm2020\chromedriver.exe'
# 关闭左上方 Chrome 正受到自动测试软件的控制的提示
options = webdriver.ChromeOptions()
options.add_experimental_option('useAutomationExtension', False)
options.add_experimental_option("excludeSwitches", ['enable-automation'])
browser = webdriver.Chrome(executable_path=chrome_driver, options=options)
browser.get('https://weixin.sogou.com/')
# browser.maximize_window()
# 设定最长等待时间  在10s内发现了输入框已经加载出来后就输入“网易云热评墙”
wait = WebDriverWait(browser, 10)
_input = wait.until(ec.presence_of_element_located((By.NAME, 'query')))
# 搜索框中输入内容
_input.send_keys('网易云热评墙')
# class定位   模拟点击搜文章
browser.find_element_by_xpath("//input[@class='swz']").click()
num = 0


def get_news():
    # 全局变量  统计文章数  记序
    global num
    article_lis = browser.find_elements_by_xpath('//ul[@class="news-list"]/li')
    for article in article_lis:
        num += 1
        # 获取文章title
        title = article.find_element_by_xpath('.//h3/a').text
        # 获取文章发表日期
        date = article.find_element_by_xpath('.//span[@class="s2"]').text
        # 文章发表的日期如果较近可能显示的为  1天前 12小时前 30分钟前  需要进行处理
        # 可以用 datetime 模块根据时间差求出具体时间
        # 然后格式化为 2020-8-31 这样的格式
        if '前' in date:
            today = datetime.datetime.today()
            if '天' in date:
                delta = datetime.timedelta(days=int(date[0]))
            elif '小时' in date:
                delta = datetime.timedelta(hours=int(date.replace('小时前', '')))
            else:
                delta = datetime.timedelta(minutes=int(date.replace('分钟前', '')))
            date = (today - delta).strftime('%Y-%m-%d')
        # 获取链接
        link = article.find_element_by_xpath('.//h3/a').get_attribute('href')
        sheet.append([num, title, date, link])
        print(num, title, date)
        print(link)
        print('*' * 25)


for i in range(10):
    get_news()
    if i == 9:
        # 如果访问到第十页则跳出循环  不需要点击“下一页”
        break
    browser.find_element_by_id("sogou_next").click()
    # 休眠  防止爬取过快  中途又让扫码登录
    time.sleep(random.randint(3, 5))

# 点登录
browser.find_element_by_name('top_login').click()

# 等待扫码登录上去   直到可以再点击下一页  退出循环
while True:
    try:
        next_page = browser.find_element_by_id("sogou_next")
        break
    except Exception as e:
        logging.info(e.args[0])
        time.sleep(2)
next_page.click()

# 登录上后  继续爬取文章信息
while True:
    get_news()
    try:
        browser.find_element_by_id("sogou_next").click()
        time.sleep(random.randint(3, 5))
    # 直到不存在下一页  爬取结束
    except Exception as e:
        logging.info(e.args[0])
        break

# 保存数据  输出日志信息  退出浏览器
wb.save(filename='articles_info.xlsx')
logging.info(f'共获取{num}条文章信息')
browser.quit()

运行效果如下:

在这里插入图片描述

2020-08-31 12:33:37,169 - INFO: 共获取957条文章信息

在这里插入图片描述

作者:叶庭云
CSDN:https://blog.csdn.net/fyfugoyfa
本文仅用于交流学习,未经作者允许,禁止转载,更勿做其他用途,违者必究。
文章对你有所帮助的话,欢迎给个赞或者 star 呀,你的支持是对作者最大的鼓励,不足之处可以在评论区多多指正,交流学习呀。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页