前提:
1.安装selenium包:pip install selenium
2.安装MySQL数据库,并下载Navicat可视化工具
Navicat可视化工具链接:
https://pan.baidu.com/s/1xOzg2Rp9L4LVv15QmRkqbQ
提取码: 1ck5
3.下载Firefox驱动器
注意:
这里要保证Firefox、geckodriver、selenium三者的版本相互兼容,不然会出现错误或者驱动不了Firefox浏览器的情况。
这里提供一篇博客,讲述如何安装三者,保证相互兼容:
相互兼容问题
请先看源码,源码中有一些不明白的地方,在从这里查
cursor.execute('use news')
# 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
dict = {'军事':'military','娱乐':'entertainment','科技':'science','体育':'sport'}
`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,选择
然后定位到需要爬取的新闻:
对于每一篇具体新闻,只需要利用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()