一直想学python,在中国大学慕课上发现了嵩老师的python系列专题课程,就首先试着听了听嵩老师的爬虫课,虽然时间有点短并且内容也不够深入,但是讲得很生动,于是就记了一些笔记,也稍微加入了一些自己的见解和总结

Requests库


主要方法

Response对象的常用属性

1.常用r.encoding = r.apparent_encoding来防止页面乱码。

2.使用r.raise_for_status()在返回状态不是200时产生异常

其他使用技巧

伪装成浏览器:

r=requests.get(url,headers={'user-agent':'Mozilla/5.0'})

Robots协议


查看方法

url/robots.txt

BeautifulSoup库


获得soup

soup=BeautifulSoup('<html>...</html>','html.parser')

常用解析器:

BeautifulSoup基本元素

标签树的遍历

下行遍历

平行遍历

友好显示

print(soup.prettify())

常用的信息表示形式与信息提取方法

BeautifulSoup标签查找方法

案例:中国大学排名定向爬虫

format函数

"{:^10}\t{:^6}\t{:^10}".format("排名","学校名称""总分")

解决中文对齐问题:

"{0:^10}\t{1:{3}^6}\t{2:^10}".format("排名","学校名称","总分",chr(12288))

chr(12288) 表示中文空格:{3}表示用format函数中索引为3的参数进行填充

Re库


常用符号

. 匹配任意单个字符
[] 字符集,对单个字符给出取值范围
[^] “非”字符集,对单个字符给出排除范围
* 前一个字符0次或多次扩展
+ 1次或多次扩展
? 0次或1次扩展
| 左右表达式任意一个
{m} 前一个字符扩展m次
{m,n} 扩展m至n次(含n)
^ 匹配字符串开头
$ 匹配字符串结尾
()  
\d 数字,等价与[0-9]
\w 单词字符,等价与[A-Za-z0-9_]

经典正则表达式

^[A-Za-z]+$ 由26个字母组成的字符串
[\u4e00-\u9fa5] 匹配中文字符
(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]) 匹配ip地址

Python的raw string类型

r'text' 则python不会对字符串中的转义符进行转义,正则表达式一般使用raw string

Re库主要函数

flags包括如下:

  • re.IGNORECASE re.I 忽略大小写匹配
  • re.MULTILINE re.M 正则表达式的^操作符能将每行当做匹配开始
  • re.DOTALL re.S 正则表达式的.操作符可以匹配包括换行符在内的一切字符,如果不指定这个模式,则.不能匹配换行符

Re库的另一种等价用法

pat=re.compile(r'[1-9]\d{5}')
rst=pat.search('BIT 100081')

Match对象介绍

Match表示一次匹配的结果,包含很多匹配信息

Match对象的属性

Match对象的方法

贪婪匹配与最小匹配

Re库默认采用贪婪匹配

最小匹配操作符

案例

网站选取心态:不要纠结与某个网站,多找信息源尝试

判断一个元素是否是标签:

import bs4
isinstance(tr, bs4.element.Tag)

注:前面说的那几个BeautifuSoup元素都是在bs4的element的模块下

Scrapy框架入门


框架结构

Scrapy的框架结构 5个组件,2个Middleware,包括Downloader Middleware和Spider Middleware

Scrapy常用命令行

Scrapy爬虫编写步骤

步骤1

建立一个scrapy爬虫工程,即生成工程目录

步骤二

在工程中产生一个scrapy爬虫。

进入刚刚创建的目录,输入如下命令:

spiders目录下会生成 爬虫名称.py,该命令仅用于生成 爬虫名称.py,该文件也可以手动生成。

步骤三

示例如下: 代码示例 另一个等价版本,使用yield生成器: yield版本代码示例

步骤四

运行爬虫,命令如下:

yield关键字

包含yield语句的函数是一个生成器,生成器每次产生一个值,然后被冻结,被唤醒后再产生一个值,不断往复。

示例:

def gen(n):
    for i in range(n):
        yield i**2

for i in gen(5):
    print(i, " ", end="")

输出:

Scrapy爬虫框架的使用步骤

  1. 创建一个工程和Spider模板
  2. 编写Spider
  3. 编写Item Pipeline
  4. 优化配置策略

Scrapy中的几种数据类型

Request类

含义:表示一个http请求,由Spider生成,Downloader执行

属性和方法:

Response类

含义:表示一个http响应,由Downloader生成,Spider处理

属性和方法:

Item类

含义:表示一个从html页面中提取的信息内容,由Spider生成,Item Pipline处理,Item类似字典类型,可以按照字典类型操作

Scrapy支持的信息提取方法

股票数据爬虫案例

非终结parse方法

是一个Request对象的生成器

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

终结parse方法

也是一个生成器

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'>.*</dt>', keyList[i])[0][1:-5]
        try:
            val = re.findall(r'\d+\.?.*</dd>', 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

编写Pipelines

步骤:

  1. 配置pipelines.py
  2. 定义对爬取项的处理类
  3. 配置settings.py的ITEM_PIPELINES选项 示例:

编写pipelines.py:

方法运行顺序为open_spider->process_item->close_spider

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:

ITEM_PIPELINES = {
    'BaiduStocks.pipelines.BaidustocksInfoPipeline': 300,
}

300的大小表示执行顺序

优化配置