第3次作业-MOOC学习笔记:Python网络爬虫与信息提取

1.注册中国大学MOOC

2.选择北京理工大学嵩天老师的《Python网络爬虫与信息提取》MOOC课程

3.学习完成第0周至第4周的课程内容,并完成各周作业

第一周作业:Requests库的爬取性能分析

尽管Requests库功能很友好、开发简单(其实除了import外只需一行主要代码),但其性能与专业爬虫相比还是有一定差距的。请编写一个小程序,“任意”找个url,测试一下成功爬取100次网页的时间。(某些网站对于连续爬取页面将采取屏蔽IP的策略,所以,要避开这类网站。)
请回复代码,并给出url及在自己机器上的运行时间。

import requests

def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)
        r.raise_for_status() #如果状态不是200,引发HTTPError异常
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return '产生异常'

def time_count(url):
    import time
    time_start= time.time()
    count=1
    while True:
        a=getHTMLText(url)
        if a != '产生异常':
            print('第{}次爬取成功'.format(count))
            count+=1
            if count == 101:
                break
    time_end= time.time()
    print('100次测试成功所需时间',time_end-time_start,'s')
   
 if __name__=='__main__':
    url = 'https://www.baidu.com'
    time_count(url)

 第3次作业-MOOC学习笔记:Python网络爬虫与信息提取_第1张图片

 

 第二周作业:中国大学排名定向爬虫(优化)

import requests
from bs4 import BeautifulSoup
import bs4
 
def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""
 
def fillUnivList(ulist, html):
    soup = BeautifulSoup(html, "html.parser")
    for tr in soup.find('tbody').children:
        if isinstance(tr, bs4.element.Tag):
            tds = tr('td')
            ulist.append([tds[0].string, tds[1].string, tds[3].string])
 
def printUnivList(ulist, num):
    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","学校名称","总分",chr(12288)))
    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))
     
def main():
    uinfo = []
    url = 'https://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20) # 20 univs
main()

 第3次作业-MOOC学习笔记:Python网络爬虫与信息提取_第2张图片

第三周作业:

淘宝商品比价定向爬虫:

import requests
import re
 
def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ""
     
def parsePage(ilt, html):
    try:
        plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"',html)
        tlt = re.findall(r'\"raw_title\"\:\".*?\"',html)
        for i in range(len(plt)):
            price = eval(plt[i].split(':')[1])
            title = eval(tlt[i].split(':')[1])
            ilt.append([price , title])
    except:
        print("")
 
def printGoodsList(ilt):
    tplt = "{:4}\t{:8}\t{:16}"
    print(tplt.format("序号", "价格", "商品名称"))
    count = 0
    for g in ilt:
        count = count + 1
        print(tplt.format(count, g[0], g[1]))
         
def main():
    goods = '书包'
    depth = 3
    start_url = 'https://s.taobao.com/search?q=' + goods
    infoList = []
    for i in range(depth):
        try:
            url = start_url + '&s=' + str(44*i)
            html = getHTMLText(url)
            parsePage(infoList, html)
        except:
            continue
    printGoodsList(infoList)
     
main() 

股票数据定向爬虫(优化):

import requests
from bs4 import BeautifulSoup
import traceback
import re
 
def getHTMLText(url, code="utf-8"):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = code
        return r.text
    except:
        return ""
 
def getStockList(lst, stockURL):
    html = getHTMLText(stockURL, "GB2312")
    soup = BeautifulSoup(html, 'html.parser') 
    a = soup.find_all('a')
    for i in a:
        try:
            href = i.attrs['href']
            lst.append(re.findall(r"[s][hz]\d{6}", href)[0])
        except:
            continue
 
def getStockInfo(lst, stockURL, fpath):
    count = 0
    for stock in lst:
        url = stockURL + stock + ".html"
        html = getHTMLText(url)
        try:
            if html=="":
                continue
            infoDict = {}
            soup = BeautifulSoup(html, 'html.parser')
            stockInfo = soup.find('div',attrs={'class':'stock-bets'})
 
            name = stockInfo.find_all(attrs={'class':'bets-name'})[0]
            infoDict.update({'股票名称': name.text.split()[0]})
             
            keyList = stockInfo.find_all('dt')
            valueList = stockInfo.find_all('dd')
            for i in range(len(keyList)):
                key = keyList[i].text
                val = valueList[i].text
                infoDict[key] = val
             
            with open(fpath, 'a', encoding='utf-8') as f:
                f.write( str(infoDict) + '\n' )
                count = count + 1
                print("\r当前进度: {:.2f}%".format(count*100/len(lst)),end="")
        except:
            count = count + 1
            print("\r当前进度: {:.2f}%".format(count*100/len(lst)),end="")
            continue
 
def main():
    stock_list_url = 'https://quote.eastmoney.com/stocklist.html'
    stock_info_url = 'https://gupiao.baidu.com/stock/'
    output_file = 'D:/BaiduStockInfo.txt'
    slist=[]
    getStockList(slist, stock_list_url)
    getStockInfo(slist, stock_info_url, output_file)
 
main()

第四周作业:股票数据Scrapy爬虫 

 

# -*- coding: utf-8 -*-
import scrapy
import re
 
 
class StocksSpider(scrapy.Spider):
    name = "stocks"
    start_urls = ['https://quote.eastmoney.com/stocklist.html']
 
    def parse(self, response):
        for href in response.css('a::attr(href)').extract():
            try:
                stock = re.findall(r"[s][hz]\d{6}", href)[0]
                url = 'https://gupiao.baidu.com/stock/' + stock + '.html'
                yield scrapy.Request(url, callback=self.parse_stock)
            except:
                continue
 
    def parse_stock(self, response):
        infoDict = {}
        stockInfo = response.css('.stock-bets')
        name = stockInfo.css('.bets-name').extract()[0]
        keyList = stockInfo.css('dt').extract()
        valueList = stockInfo.css('dd').extract()
        for i in range(len(keyList)):
            key = re.findall(r'>.*', keyList[i])[0][1:-5]
            try:
                val = re.findall(r'\d+\.?.*', valueList[i])[0][0:-5]
            except:
                val = '--'
            infoDict[key]=val
 
        infoDict.update(
            {'股票名称': re.findall('\s.*\(',name)[0].split()[0] + \
             re.findall('\>.*\<', name)[0][1:-1]})
        yield infoDict

  

# -*- coding: utf-8 -*-
 
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
 
 
class BaidustocksPipeline(object):
    def process_item(self, item, spider):
        return item
 
class BaidustocksInfoPipeline(object):
    def open_spider(self, spider):
        self.f = open('BaiduStockInfo.txt', 'w')
 
    def close_spider(self, spider):
        self.f.close()
 
    def process_item(self, item, spider):
        try:
            line = str(dict(item)) + '\n'
            self.f.write(line)
        except:
            pass
        return item

settings.py文件中被修改的区域:  

# Configure item pipelines
# See https://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    'BaiduStocks.pipelines.BaidustocksInfoPipeline': 300,
}

  

4.提供图片或网站显示的学习进度,证明学习的过程。

 第3次作业-MOOC学习笔记:Python网络爬虫与信息提取_第3张图片

5.写一篇不少于1000字的学习笔记,谈一下学习的体会和收获。

  刚开始对爬虫仅停留在基础的位置,并不是很了解。但通过爬虫的这门入门启蒙课程,个人觉得非常适合python初学者,复习掌握python基本编程语法后,就可以开始学习这门课程,通过几周嵩老师的讲解和编写爬虫实例,惊叹python语言的魅力所在,高效与快捷增加了我对python爬虫深入学习的兴趣。

  一开始需要环境配置,安装各种第三方模块等等,有些东西看懂了,但结果自己写代码还是很困难,所以其实个人觉得尽量不要系统地去啃一些东西,根据嵩老师课程上的实例,举一反三,找一些其他的例子入手,这样反而更容易掌握。因为爬虫这种技术,既不需要系统的精通一门语言,也不需要多么高深的数据库技术,从实操中去学习python中零散的知识,可能可以保证每次学到的都是最需要的部分。

     在此次课程的学习中特别注意到一个修改User-Agent爬虫防屏蔽策略。User-Agent是一种最常见的伪装浏览器的手段。User-Agent是指包含浏览器信息、操作系统信息等的一个字符串,也称之为一种特殊的网络协议。服务器通过它判断当前访问对象是浏览器、邮件客户端还是网络爬虫。在request.headers里可以查看user-agent,关于怎么分析数据包、查看其User-Agent等信息,这个在前面的文章里提到过。具体方法可以把User-Agent的值改为浏览器的方式,甚至可以设置一个User-Agent池(list,数组,字典都可以),存放多个“浏览器”,每次爬取的时候随机取一个来设置request的User-Agent,这样User-Agent会一直在变化,防止被墙。在爬取中国大学排名出现的问题,,用requests和BeautifulSoup库是无法获取它的信息的,其次还要网站robots协议是否符合相关规定。爬取总体分成三个步骤:从网络上获取大学排名网页内容,定义函数数:getHTMLText();提取网页中信息并放到合适的数据结构定义函数:fillUnivList();利用数据结构展示并输出结果,定义函数:printUnivList()有了这三个函数,我们可以把程序封装成这三个模块,可读性更好。 

    使用bs4进行xml解析时,由于每个节点属性不完全相同,当统一使用一个方法访问节点属性的时候一定要加try,防止程序意外中断;在使用python语言的时候,为了安全,要注意函数的返回值,特别是类型判断;网页抓取要用try,动态数据类型尽量也要。对于url请求分析有三点,认真分析页面结构,查看js响应的动作;借助浏览器分析js点击动作所发出的请求url;将此异步请求的url作为scrapy再次进行抓取。

     课程上最后一周还讲了Scrapy框架,它是Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类。

 

你可能感兴趣的:(第3次作业-MOOC学习笔记:Python网络爬虫与信息提取)