Selenium驱动firefox爬取今日头条并存放在MySQL数据库中

Selenium驱动firefox爬取今日头条

前提:
1.安装selenium包:pip install selenium
2.安装MySQL数据库,并下载Navicat可视化工具
Navicat可视化工具链接:
https://pan.baidu.com/s/1xOzg2Rp9L4LVv15QmRkqbQ
提取码: 1ck5
3.下载Firefox驱动器
注意:
这里要保证Firefox、geckodriver、selenium三者的版本相互兼容,不然会出现错误或者驱动不了Firefox浏览器的情况。
这里提供一篇博客,讲述如何安装三者,保证相互兼容:
相互兼容问题

请先看源码,源码中有一些不明白的地方,在从这里查

说明资料
Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第1张图片Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第2张图片

cursor.execute('use news')

Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第3张图片

# SQL语句的意思是建立一个序号自增,包含title\title_pic\author\times\article_pic\article的表格
	
    sql = '''
        create table {}(
        id int(11) not null auto_increment primary key,
        title varchar(100),
        title_pic varchar(100),
        author varchar(50),
        times varchar(30),
        article_pic varchar(100),
        article text
        )
        
    '''.format(path)

    try:
        cursor.execute(sql)
    except:
        pass

Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第4张图片

dict = {'军事':'military','娱乐':'entertainment','科技':'science','体育':'sport'}

Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第5张图片

`titles= brower.find_elements_by_xpath('//div[@class="title-box"]/a')
    title_pics = brower.find_elements_by_xpath('//a[@class="img-wrap"]/img')

如何不会利用xpath的话,也可以这样:
打开页面,按F12,选择
Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第6张图片然后定位到需要爬取的新闻:

Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第7张图片Selenium驱动firefox爬取今日头条并存放在MySQL数据库中_第8张图片通过这种方法也可以获取xpath。

对于每一篇具体新闻,只需要利用BeautifulSoup解析后,利用其页面选择方法即可获取

代码:

from selenium import webdriver
import re
import os
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
from bs4 import BeautifulSoup
from selenium.webdriver.firefox.options import Options
import pymysql
import requests
import urllib.request
all_comments = []

# 指定无头爬取,加快速度,如果是初学者,不建议这样做,可视化驱动可以让我们理解具体爬取过程
options = Options()
options.add_argument('--headless')

brower = webdriver.Firefox(firefox_options=options)

# 连接MySQL
db = pymysql.connect(host='localhost',user='root',password='118922',port=3366)
cursor = db.cursor()
# 指定使用哪个数据库,这里指定使用news数据库
cursor.execute('use news')

# 这里只爬取四类新闻,其他新闻操作类似
dict = {'军事':'military','娱乐':'entertainment','科技':'science','体育':'sport'}



def main():
	# SQL语句的意思是建立一个序号自增,包含title\title_pic\author\times\article_pic\article的表格
	
    sql = '''
        create table {}(
        id int(11) not null auto_increment primary key,
        title varchar(100),
        title_pic varchar(100),
        author varchar(50),
        times varchar(30),
        article_pic varchar(100),
        article text
        )
        
    '''.format(path)

    try:
        cursor.execute(sql)
    except:
        pass

    title_list = []
    link_list = []
    title_pic_list = []
    all = []

	# 进入头条界面
    brower.get('https://landing.toutiao.com/')

    brower.implicitly_wait(10)

	# 由于军事是在“更多”这个标签下,相当于二级菜单,故需要单独处理
    if keyword != '军事':
        brower.find_element_by_link_text(keyword).click()
        time.sleep(5)
        # 重复点击,防止爬取相同新闻
        brower.find_element_by_link_text(keyword).click()
        brower.implicitly_wait(5)
    else:
        more = brower.find_element_by_link_text('更多')
        # 控制鼠标移到二级菜单进行处理
        ActionChains(brower).move_to_element(more).perform()
        #brower.implicitly_wait(10)
        brower.find_element_by_link_text('军事').click()
        time.sleep(2)
        #brower.find_element_by_link_text('军事').click()

	# 通过selenium的查找方法找到需要的内容
    titles= brower.find_elements_by_xpath('//div[@class="title-box"]/a')
    title_pics = brower.find_elements_by_xpath('//a[@class="img-wrap"]/img')
    
    for title,title_pic,_ in zip(titles,title_pics,range(50)):
        title_list.append(title.text)
        link_list.append(title.get_attribute('href'))
        title_pic_list.append(title_pic.get_attribute('src'))

	# 遍历新闻链节,进入新闻内容页面
    for title,link,pic_link in zip(title_list,link_list,title_pic_list):
         dict = {}
         brower.get(link)
         time.sleep(1)
         article = ''
         # 获取源码,然后利用BeautifulSoup解析页面
         html = brower.page_source
         soup = BeautifulSoup(html,'html.parser')
         try:
             contents = soup.find('div',class_='article-content').find_all('p')
             photos = soup.find('div',class_='article-content').find_all('img')
             time_authors = soup.find('div',class_='article-sub')
             # 这里获取的是时间和作者,故需利用正则匹配
             time_authors_text = time_authors.get_text()
             author = re.match('(^.*?)\d',time_authors_text)
             times =  re.search('\d.*',time_authors_text)
             # 获取具体内容
             for content in contents:
                 if content.get_text():
                     article += content.get_text().strip() + '\n'
             # 将所以要获取的内容以字典形式保存
             dict = {
                 'title':title,
                 'author':author.group(1),
                 'time':times.group(0),
                 'article':article,
                 'title_pic':pic_link,
                 'article_pic':photos[0].get('src')
             }

             all.append(dict)
         except:
             pass

    for item in all:
        title = item['title']
        title_pic = item['title_pic']
        author = item['author']
        times = item['time']
        article_pic = item['article_pic']
        article = item['article']
	# 将获取的内容存入数据库中
        sql = '''
            insert ignore into {}(title,title_pic,author,times,article_pic,article)
            VALUES (%s,%s,%s,%s,%s,%s)
            '''.format(path)

        try:
            cursor.execute(sql,(title,title_pic,author,times,article_pic,article))
            db.commit()
            print('插入成功')
        except:
            db.rollback()
            print('插入失败')

if __name__ == '__main__':
    for k, v in dict.items():
        keyword = k
        path = v
        main()
    brower.close()
    db.close()

你可能感兴趣的:(python)