Python爬虫程序示例(正则表达式、BeautifulSoup 、selenium)

1. 基于百度新闻爬取对应关键字的新闻标题

代码:

  • 来源:
    中国大学MOOC(南开大学 – Python编程基础 – 王恺 、李妍 、闫晓玉 、施莺莺 、李涛)
import re # re模块主要是通过正则表达式的匹配,从网页中提取想要的信息
import requests # 从指定的网页上爬取数据
from urllib.parse import quote #导入quote方法对URL中的字符进行编码
class BaiduNewsCrawler: #定义BaiduNewsCrawler类
	headersParameters = { #发送HTTP请求时的HEAD信息
		'Connection': 'Keep-Alive',
		'Accept': 'text/html, application/xhtml+xml,*/*',
		'Accept-Language':
			'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
		'Accept-Encoding': 'gzip, deflate',
		'User-Agent':
		'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
		}
''' ----------------------------注释-------------------------------------------
    headersParameters中保存了请求头的信息,如:
    headersParameters = { #发送HTTP请求时的HEAD信息
        'Connection': 'Keep-Alive',
            # Connection决定当前的事务完成后,是否会关闭网络连接。如果该值是“Keep-Alive”,网络连接就是持久
        'Accept': 'text/html, application/xhtml+xml, */*',
            #浏览器接收的媒体类型,text/html代表HTML格式,application/xhtml+xml代表XHTML格式,*/* 代表浏览器可以处理所有类型
        'Accept-Language':     'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
            #浏览器申明自己接收的语言
        'Accept-Encoding': 'gzip, deflate',
            #浏览器申明自己接收的编码方式:通常指定压缩、是否支持压缩、支持什么方式压缩(gzip/default)
        'User-Agent': 'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
            #告诉HTTP服务器客户端浏览器使用的操作系统和浏览器的版本和名称
    }
    ----------------------------注释-------------------------------------------
 '''
	def __init__(self, keyword, timeout): #定义构造方法
		self.url='http://news.baidu.com/ns?word='+ quote(keyword) + '&tn=news&from=news&cl=2&rn=20&ct=1' #要爬取的新闻网址,keyword:搜索的关键词,百度新闻固定的搜索关键字地址
		self.timeout=timeout #连接超时时间设置(单位:秒)
	def GetHtml(self): #定义GetHtml方法
		request=requests.get(self.url, timeout=self.timeout,
			headers=self.headersParameters) #根据指定网址爬取网页
		request.encoding = 'utf-8'
		self.html=request.text #获取新闻网页内容
	def GetTitles(self): #定义GetTitles方法
		self.titles = re.findall(r'

([\s\S]*?)

'
,self.html) #匹配新闻标题,返回的是列表 for i in range(len(self.titles)): #对于每一个标题 self.titles[i]=re.sub(r'<[^>]+>','',self.titles[i]) #去除所有HTML标记,即<...> self.titles[i]=self.titles[i].strip() #将标题两边的空白符去掉 def PrintTitles(self): #定义PrintTitle方法 no=1 for title in self.titles: #输出标题 print(str(no)+':'+title) no+=1 if __name__ == '__main__': bnc = BaiduNewsCrawler('南开大学',30) #创建BaiduNewsCrawler类对象 bnc.GetHtml() #获取新闻网页的内容 bnc.GetTitles() #获取新闻标题 bnc.PrintTitles() #输出新闻标题

运行结果:
1:南开大学MBA项目2019招生信息
2:南开大学“二次选拔”受欢迎 近八成新生参加考试“自选”成才之路
3:南开大学计算机系到演员 张桐回顾“不安分”的青春
4:南开大学一批教师和集体获得天津市荣誉表彰
5:南开大学校长曹雪涛寄语新生:
6:1亿元!南开大学校友张文中捐巨资支持母校发展
……
用正则表达式对爬取的网页进行分析前,可以先在浏览器下访问网页,按键盘上的F12功能键出现浏览器的调试工具查看页面上的元素;然后查看要获取元素的HTML代码,并根据HTML代码书写正则表达式进行元素匹配。
例如,在第39行代码中:

([\s\S]*?)


即是每条新闻标题对应的HTML代码格式。

提示:因为程序输出的是实时从百度新闻上抓取的新闻标题,所以实际运行该程序时会看到不同的输出结果。

2. 爬取南开新闻标题并存储到本地文件中

2.1 根据正则表达式查找网页内容

代码:

import re
import requests
from urllib.parse import quote #导入quote方法对URL中的字符进行编码
class NankaiNewsCrawler: #定义NankaiNewsCrawler类
    headersParameters = { #发送HTTP请求时的HEAD信息
        'Connection': 'Keep-Alive',
        'Accept': 'text/html, application/xhtml+xml, */*',
        'Accept-Language': 
        'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
        'Accept-Encoding': 'gzip, deflate',
        'User-Agent': 
        'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
    }
    '''
    headersParameters中保存了请求头的信息,如:
    headersParameters = { #发送HTTP请求时的HEAD信息
        'Connection': 'Keep-Alive',
            # Connection决定当前的事务完成后,是否会关闭网络连接。如果该值是“Keep-Alive”,网络连接就是持久
        'Accept': 'text/html, application/xhtml+xml, */*',
            #浏览器接收的媒体类型,text/html代表HTML格式,application/xhtml+xml代表XHTML格式,*/* 代表浏览器可以处理所有类型
        'Accept-Language':     'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
            #浏览器申明自己接收的语言
        'Accept-Encoding': 'gzip, deflate',
            #浏览器申明自己接收的编码方式:通常指定压缩、是否支持压缩、支持什么方式压缩(gzip/default)
        'User-Agent': 'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
            #告诉HTTP服务器客户端浏览器使用的操作系统和浏览器的版本和名称
    }
    '''
     
    def __init__(self, timeout): #定义构造方法
        self.url='https://news.nankai.edu.cn/ywsd/index.shtml'
        self.timeout=timeout #连接超时时间设置(单位:秒)
        self.titles = []
    def GetHtml(self): #定义GetHtml方法
        request=requests.get(self.url, timeout=self.timeout, headers=self.headersParameters)      #根据指定网址爬取网页
        request.encoding = 'utf-8'
        self.html=request.text #获取新闻网页内容
    def GetTitles(self): #定义GetTitles方法
        titles = re.findall(r'
([\s\S]*?)
'
,self.html) #匹配新闻标题 通过F12查看、查找 for i in range(len(titles)): #对于每一个标题 temp=re.sub(r'<[^>]+>','',titles[i]) #去除所有HTML标记,即<...> self.titles.append(temp.strip()) #将标题两边的空白符去掉 def PrintTitles(self): #定义PrintTitle方法 no=1 for title in self.titles: #显示标题 print(str(no)+':'+title) no+=1 def ExportToFile(self, filepath): #定义ExportToFile方法,将标题输出到文件中 with open(filepath, 'w', encoding='utf-8') as f: no=1 for title in self.titles: f.write(str(no)+':'+title+'\n') no+=1 def GetTitlesNum(self): #定义GetTitlesNum方法,返回已获取的新闻标题数 return len(self.titles) if __name__ == '__main__': bnc = NankaiNewsCrawler(30) #创建NankaiNewsCrawler类对象 bnc.GetHtml() #获取新闻网页的内容 bnc.GetTitles() #获取新闻标题 bnc.PrintTitles() #显示新闻标题 bnc.ExportToFile('newstitlelist.txt') #将新闻标题保存到文件中
2.2 根据BeautifulSoup工具包查找网页内容

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。
Beautiful Soup 4.4.0 文档
Beautiful Soup 最新版文档
代码:

import re
import requests
from urllib.parse import quote #导入quote方法对URL中的字符进行编码
from bs4 import BeautifulSoup #导入BeautifulSoup
class NankaiNewsCrawler: #定义NankaiNewsCrawler类
    headersParameters = { #发送HTTP请求时的HEAD信息
        'Connection': 'Keep-Alive',
        'Accept': 'text/html, application/xhtml+xml, */*',
        'Accept-Language': 
        'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
        'Accept-Encoding': 'gzip, deflate',
        'User-Agent': 
        'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
    }
    '''
    headersParameters中保存了请求头的信息,如:
    headersParameters = { #发送HTTP请求时的HEAD信息
        'Connection': 'Keep-Alive',
            # Connection决定当前的事务完成后,是否会关闭网络连接。如果该值是“Keep-Alive”,网络连接就是持久
        'Accept': 'text/html, application/xhtml+xml, */*',
            #浏览器接收的媒体类型,text/html代表HTML格式,application/xhtml+xml代表XHTML格式,*/* 代表浏览器可以处理所有类型
        'Accept-Language':     'en-US,en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3',
            #浏览器申明自己接收的语言
        'Accept-Encoding': 'gzip, deflate',
            #浏览器申明自己接收的编码方式:通常指定压缩、是否支持压缩、支持什么方式压缩(gzip/default)
        'User-Agent': 'Mozilla/6.1 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko'
            #告诉HTTP服务器客户端浏览器使用的操作系统和浏览器的版本和名称
    }
    '''
     
    def __init__(self, timeout): #定义构造方法
        self.url='https://news.nankai.edu.cn/ywsd/index.shtml'
        self.timeout=timeout #连接超时时间设置(单位:秒)
        self.titles = []
    def GetHtml(self): #定义GetHtml方法
        request=requests.get(self.url, timeout=self.timeout, headers=self.headersParameters)      #根据指定网址爬取网页
        request.encoding = 'utf-8'
        self.html=request.text #获取新闻网页内容
    def GetTitles(self): #定义GetTitles方法
        bs = BeautifulSoup(self.html, 'html.parser') #将我们从网页上获取的html文本信息解析成html的文档树,结果返回一个 BeautifulSoup 的对象
        titles = bs.find_all('div',{'align':'left'})   #查找align属性为left的所有div
        # 根据html标签具有的属性值来确定从哪爬取数字
        #find_all() 方法将返回文档中符合条件的所有tag,返回结果是列表
        for i in range(len(titles)):       #对于每一个标题
            self.titles.append(titles[i].string)#获取文本信息 .string 查看官方文档
    def PrintTitles(self): #定义PrintTitle方法
        no=1
        for title in self.titles: #显示标题
            print(str(no)+':'+title)
            no+=1
    def ExportToFile(self, filepath): #定义ExportToFile方法,将标题输出到文件中
        with open(filepath, 'w', encoding='utf-8') as f:
            no=1
            for title in self.titles:
                f.write(str(no)+':'+title+'\n')
                no+=1
    def GetTitlesNum(self): #定义GetTitlesNum方法,返回已获取的新闻标题数
        return len(self.titles)
 
if __name__ == '__main__':
    bnc = NankaiNewsCrawler(30) #创建NankaiNewsCrawler类对象
    bnc.GetHtml() #获取新闻网页的内容
    bnc.GetTitles() #获取新闻标题
    bnc.PrintTitles() #显示新闻标题
    bnc.ExportToFile('newstitlelist.txt') #将新闻标题保存到文件中

3.爬取携程酒店评价(selenium)

Selenium 是支持 web 浏览器自动化的一系列工具和库的综合项目。需要安装 浏览器Driver
chromedriver下载地址
Selenium官方文档(中文版)
selenium工具包可以模拟浏览器的操作
代码:

# -*- coding: utf-8 -*-
"""
Created on Wed Nov 20 21:50:13 2019
 
@author: admin
"""
 
from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Options
 
class CtripCommentsCrawler:
    def __init__(self, url):
        self.url = url
     
    def getdata(self, pagenum, filepath):
        try:
            option = Options()
            option.add_experimental_option('excludeSwitches', ['enable-automation']) #启用开发者模式
            driver = webdriver.Chrome(options=option)
            driver.get(url)
            with open(filepath, 'w', encoding='utf-8') as f:
                for pageno in range(1,pagenum+1):
                    trynum = 0
                    while True:
                        try:
                            comments = driver.find_elements_by_css_selector('#divCtripComment > div.comment_detail_list > div')
                            #F12找到对应元素,右键copy——selector
                            #divCtripComment > div.comment_detail_list > div:nth-child(1)
                            #,再修改
                            break
                        except:
                            trynum += 1
                            if trynum > 6:
                                break
                            time.sleep(5)
                            continue
                    for comment in comments:
                        comment_main = comment.find_element_by_class_name('comment_main')
                        comment_title = comment_main.find_element_by_class_name('comment_title')
                        score = comment_title.find_element_by_class_name('score')
                        n = score.find_element_by_class_name('n').text
                        #一级一级搜索
                        comment_txt = comment_main.find_element_by_class_name('comment_txt')
                        J_commentDetail = comment_txt.find_element_by_class_name('J_commentDetail').text
                        f.write('{0},{1}\n'.format(n, J_commentDetail))
                    print('page. {0}'.format(pageno))
                    try:
                        nextpage = driver.find_element_by_css_selector('#divCtripComment > div.c_page_box > div > a.c_down')
                        driver.execute_script("arguments[0].click();", nextpage)
                        #nextpage.click()
                        time.sleep(5)
                    except:
                        break
        finally:
            driver.quit() #停止浏览器
         
if __name__=='__main__':
    url = 'https://hotels.ctrip.com/hotel/1073814.html?isFull=F&masterhotelid=1073814&hcityid=2#ctm_ref=hod_sr_lst_dl_n_1_2'
    crawler = CtripCommentsCrawler(url)
    crawler.getdata(5, './ctripcomments.csv')

注:

  1. requests模块在使用前需要先安装,可以在系统控制台下输入如下命令完成requests模块的下载和安装:
    pip install requests -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com
国内安装第三方模块需要镜像

pip install 包名 -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com
否则可能会出现下图错误信息
Python爬虫程序示例(正则表达式、BeautifulSoup 、selenium)_第1张图片

  1. 对爬取的网页进行分析前,可以先在浏览器下访问网页,按键盘上的F12功能键出现浏览器的调试工具查看页面上的元素;
    然后查看要获取元素的HTML代码,并根据HTML代码书写正则表达式进行元素匹配。
    或用BeautifulSoup 或selenium
爬虫常用的正则表达式

[python] 常用正则表达式爬取网页信息及分析HTML标签总结 —作者:杨秀璋

  1. 常用的HTTP请求头与响应头 – totoroKing

你可能感兴趣的:(Python学习,python,selenium)