0%

PythonDataAnalysis_1--简单网络爬虫

  使用python的requests库和BeautifulSoup4去对网页信息进行爬取和解析,获得制定信息;其中涉及Javascript渲染的动态页面,我采用了selenium + PlantomJS的动态网页爬取技术进行了爬取。

Requests库

  Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。

安装方法

Pip install requests

一般使用方法

import requests
r = requests.get("http://www.whu.edu.cn/ ") 
print(r.status_code) #返回状态码
print(r.headers) #返回Response消息报头
print(r.text) #返回响应正文
print(r.content) #以二进制编码返回响应正文

BeautifulSoup库

  BeautifulSoup 是一个可以从HTML或 XML文件中提取数据的Python库.它能够通 过转换器实现文档导航、查找、修改。

安装方法

pip install beautifulsoup4

一般使用

import requests 
r=requests.get("https://whu.edu.cn/coremail/common/index_cm40.jsp") 
demo=r.text
from bs4 import BeautifulSoup 
soup=BeautifulSoup(demo,'html.parser') #html解析器
print(soup.prettify())

selenium 与 PlantomJS

  selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行处理(Selenium Grid)。Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可以用于任何支持JavaScript的浏览器上,可以模拟真实浏览器,自动化测试工具,支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题。

  PhantomJS 是一个基于 WebKit(WebKit是一个开源的浏览器引擎,Chrome,Safari就是用的这个浏览器引擎) 的服务器端 JavaScript API,用于无需浏览器的 Web 测试,页面访问自动化,屏幕捕获,网络监控。

安装方法

  由于新的selenium3.x版本不支持PlantomJS了,此处采用2.48.0版本:

Pip install selenium==2.48.0

PlantomJS前往plantomJS官网下载exe文件放入python安装目录下的script目录即可。

一般使用

from selenium import webdriver
url = 'http://www.zuihaodaxue.cn/ARWU2016.html'
ulist=[]
driver = webdriver.PhantomJS()
driver.get(url)
data=driver.page_source

此时得到的data即为JS渲染后的网页源代码,可以再通过BeautifulSoup进行html解析后续步骤与静态网页爬取一样。

实例1–爬取百度搜索风云榜单数据

先给代码:

import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url): 
    try: 
        r=requests.get(url)
        r.encoding=r.apparent_encoding
        return r.text
    except: 
        return ""

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser") 
    for li in soup.find('ul','list').children: 
        if isinstance(li, bs4.element.Tag): 
            span1=li.find_all('span')[0]
            a=li.find('a')
            if li.find('span','icon-fair'):
                span2=li.find('span','icon-fair')
            if li.find('span','icon-fall'):
                span2=li.find('span','icon-fall')
            if li.find('span','icon-rise'):
                span2=li.find('span','icon-rise')
            ulist.append([span1.string,a.string, span2.string])
def printUnivList(ulist, num):
    title = "{0:^24}"
    print(title.format('百度实时搜索榜'))
    tplt = "{0:^4}\t{1:{3}^8}\t{2:^12}" 
    print(tplt.format("排名", "关键词", "搜索指数", chr(12288))) 
    tpp = "{0:^4}\t{1:^12}\t{2:^16}" 
    for i in range(num): 
        u = ulist[i] 
        print(tpp.format(u[0], u[1], u[2]))
def main(): 
    ulist = [] 
    url = 'http://top.baidu.com/'
    html = getHTMLText(url) 
    fillUnivList(ulist, html)
    printUnivList(ulist, 10)
main()

代码比较简单,其中涉及到四个函数:

  • getHTMLText函数获取了网页地址,通过requests的get请求返回网页源码
  • fillUnivList函数通过BeautifulSoup解析得到的网页代码以填充ulist,其中,再查看百度实时搜索榜时发现,搜索指数栏网页开发者为了标识出增长情况对span的class作了不同处理,所以对class进行了判断。
  • PrintUnivList函数进行格式化输出,顺序扫描ulist中的每一个存入元组进行格式化输出;
  • Main函数实现过程的调用

实例2– 爬取当当图书排行榜

此处选择的目标网页当当畅销书排行榜,地址:
http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1

  其中用到的代码与前面的没有太大区别,只是针对特定网页做了一些解析上的调整,其中由于网页中图书名处a标签有的图书并未设置非属性内容,故只能将title属性作为书名进行爬取。导致了爬取的图书名出现了过长等情况。

import requests
from bs4 import BeautifulSoup
import bs4
from selenium import webdriver
def getHTMLText(url): 
    '''
    获取页面
    '''
    try:
        driver = webdriver.PhantomJS()
        driver.get(url)
        html=driver.page_source
        return html
    except: 
        return ""

def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser") 
    for li in soup.find('ul','bang_list clearfix bang_list_mode').children:
        if li.find('div')!=-1:
            num=li.find('div').string.replace(".","")
            name=li.find('div','name').find('a')['title']
            author=li.find('div','publisher_info').find('a').string
            ulist.append([num,author,name])
def printUnivList(ulist, number):
    title = "{0:^24}"
    print(title.format('当当图书畅销榜'))
    tplt = "{0:^4}\t{1:{3}^8}\t{2:^12}" 
    print(tplt.format("排名", "作者", "书籍名", chr(12288))) 
    for i in range(number): 
        u = ulist[i]
        print(tplt.format(u[0], u[1], u[2], chr(12288)))
def main(): 
    ulist = [] 
    url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-1'
    html = getHTMLText(url) 
    fillUnivList(ulist, html)
    printUnivList(ulist, 20)
main()

后文

这次主要是python的几个模块的简单使用,不多说。