当你爬数据的时候有没有遇到过向某个URL请求数据,响应回来的页面源码不全,明明在浏览器打开能看到,可到自己爬的时候就是看不到。其实是因为你爬取的页面是动态网页,很多数据是要加载才能渲染出来的。比如爬取环球网文章页面: 环球网.
这个时候通过request库就不太适合爬取动态网页了。目前主流是通过selenium去爬取。
Selenium介绍:
- Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,Selenium 可以直接调用浏览器,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器),可以接收指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏等。
在使用selenium爬取数据之前必然要先下载selenium,找到你python下的Scripts文件夹,复制路径,用cmd打开,输入pip install selenium
然后就去下载浏览器驱动
首先查看浏览器版本,本文介绍Chrome,其他浏览器自行百度。 点击查看Chrome版本
chromedriver与chrome各版本及下载
接下来就展示一下如何使用selenium动态加载(下拉加载)获取环球网疫情新闻标题和链接,
# -*- coding: utf-8 -*-
import requests, time, re #
from bs4 import BeautifulSoup #使用bs4解析
from selenium import webdriver #自动化测试工具
def main():
url = "https://world.huanqiu.com/article" #环球网文章url
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36"}
save_path = "./news.txt" #疫情文章和链接保存路径
get_data(url) #获取网页数据
parse_data(url) #解析提取所需数据
save_data(save_path,url) #保存数据
pass
def get_data(url):
browser = webdriver.Chrome() #创建Chrome浏览器对象,这会在电脑上在打开一个浏览器窗口
browser.get(url) #通过浏览器向服务器发送URL请求
for i in range(3):
browser.execute_script("window.scrollTo(0,document.body.scrollHeight)") # 将滚动条调整至页面底部循环三次
time.sleep(2)
response = browser.page_source # 获取页面源码
soup = BeautifulSoup(response, 'lxml') # beautifulsoup 使用 lxml 解析
return soup
pass
def parse_data(url):
titles = [] #爬取到的标题列表
hrefs = [] #爬取到的标题链接列表
target_titles = [] #爬取到的疫情新闻标题列表
target_hrefs = [] #爬取到的疫情新闻标题链接列表
soup = get_data(url)
title_list = soup.select(".m-recommend-con ul li a div h4") #调用soup的选择器方法找到标题位置,返回值为列表
href_list = soup.select(".m-recommend-con ul li a") #调用soup的选择器方法找到标题链接位置,返回值为列表
for t in title_list:
title = t.string
titles.append(title) #添加至标题列表
for h in href_list:
href = h['href']
hrefs.append(href) #添加至标题链接列表
i=0
for title in titles:
if((('新冠' in title)|('疫苗' in title)|('疫情' in title)|('病毒' in title))): #通过关键字来获取疫情相关信息
target_titles.append(titles[i]) #添加至疫情新闻标题列表
target_hrefs.append("https://world.huanqiu.com"+hrefs[i]) #添加至疫情新闻标题链接列表,并通过字符串拼接成url
i = i+1
return target_titles,target_hrefs
pass
def save_data(save_path,url):
target_titles,target_hrefs = parse_data(url)
f = open(save_path, 'a', encoding="utf-8") #以追加的方式打开文件,如果不存在则创建,设置字符集为utf-8
for i in range(len(target_titles)):
f.write(target_titles[i]) #写入疫情新闻标题列表
f.write("\n") #换行
f.write(target_hrefs[i]) #写入疫情新闻标题链接列表
f.write("\n\n")
f.close() #关闭
pass
if __name__ == "__main__":
main()
pass