Python 学习笔记3 - 定向爬虫入门

时间:2022-01-30 04:19:12

3、Python 定向爬虫入门

1、基本的正则表达式

1-2正则表达式符号与方法

常用符号

  . 匹配任意字符,换行符\n除外 (占位符,几个点就是几个占位符)

  * 匹配前一个字符0次或无限次

  ? 匹配前一个字符0次或1次

  .* 贪心算法

  .*?非贪心算法

  () 括号内的数据作为结果返回

 

常用方法

  findall匹配所有符合规律的内容,返回包含结果的列表

  search 匹配并提取第一个符合规律的内容,返回一个正则表达式对象(object)

  sub替换符合规律的内容,返回替换后的值

 

常用技巧

  import re (推荐)

  from re import * (不推荐)

  from re import findall,search,sub,S (不推荐)

  不需要compile

  使用\d+匹配纯数字

 

re.S – 让点的范围匹配任何字符(包括\n),任何一行

 


 

1-3正则表达式的应用举例

 import re

 

匹配多段内容

  灵活使用findall与search

  先抓大再抓小

 

实现翻页

 

#-*-coding:utf8-*-

#
导入re库文件
import re

old_url = 'http://www.jikexueyuan.com/course/android/?pageNum=2'
total_page = 20

f = open('text.txt','r')
html = f.read()
f.close()

#爬取标题
# title = re.search('<title>(.*?)</title>',html,re.S).group(1)
# print title

#
爬取链接
# links = re.findall('href="(.*?)"',html,re.S)
# for each in links:
#     print each

#抓取部分文字,先大再小
# text_fied = re.findall('<ul>(.*?)</ul>',html,re.S)[0]
# print text_fied
# the_text = re.findall('">(.*?)</a>',text_fied,re.S)
# for every_text in the_text:
#     print every_text

#sub实现翻页
for i in range(2,total_page+1):
    new_link = re.sub('pageNum=\d+','pageNum=%d'%i,old_url,re.S)
    print new_link


 

1-4实战——制作文本爬虫

 

目标网站:http://www.jikexueyuan.com/

目标内容:课程图片

实现原理:

  1.保存网页源代码

  2.Python读文件加载源代码

  3.正则表达式提取图片网址

  4.下载图片

 

#-*-coding:utf8-*-
import re
import requests

#读取源代码文件
f = open('source.txt','r')
html = f.read()
f.close()

#匹配图片网址
pic_url = re.findall('img src="(.*?)" class="op-img-others c-img c-img6"',html,re.S)
i = 0
for each in pic_url:
    print 'now downloading:' + each
    pic = requests.get(each)
    fp = open('pic\\' + str(i) + '.jpg','wb')
    fp.write(pic.content)
    fp.close()
    i += 1

 

 

 


 

2、Python 单线程爬虫

2-1 Requests介绍和安装

Requests安装

Windows: pip install requests (在目录C:\Python27\Scripts)

Linux: sudo pip install requests

 

第三方库安装技巧

  少用easy_install因为只能安装不能卸载

  多用pip方式安装

  撞墙了怎么办?请戳->http://www.lfd.uci.edu/~gohlke/pythonlibs/

  下载后将.whl重命名为.zip

 

 

2-2 第一个网页爬虫

直接获取源代码

import requests
html = requests.get('http://tieba.baidu.com/')
print html.text

 

 

修改http头获取源代码
#hd是我们自己构造的一个字典,里面保存了user-agent
hd = {'User-Agent':'Mozilla/5.0(Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/41.0.2272.118 Safari/537.36'}
html = requests.get('http://jp.tingroom.com/yuedu/yd300p/',headers= hd)

 


 

Requests与正则表达式

单线程简单爬虫原理 – 使用requests获取网页源代码,再使用正则表达式匹配出感兴趣的内容

 

#-*—coding:utf8-*-
import requests
import re
#下面三行是编码转换的功能,大家现在不用关心。
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

#hd是我们自己构造的一个字典,里面保存了user-agent
hd = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'}
# html = requests.get('http://jp.tingroom.com/yuedu/yd300p/')
html = requests.get('http://jp.tingroom.com/yuedu/yd300p/',headers = hd)

html.encoding = 'utf-8' #这一行是将编码转为utf-8否则中文会显示乱码。
print html.text
title = re.findall('color:#666666;">(.*?)</span>',html.text,re.S)
for each in title:
    print each

chinese = re.findall('color: #039;">(.*?)</a>',html.text,re.S)
for each in chinese:
    print each

 


 

2-3 向网页提交数据

Get与post介绍

  Get是从服务器上获取数据

  Post是向服务器传送数据

  Get通过构造url中的参数来实现功能

  Post将数据放在header提交数据

 

 

分析目标网站

  网站地址:https://www.crowdfunder.com/browse/deals

  分析工具:Chrome-审核元素-Network

 

 

Request 表单提交

  核心方法:request.post

  核心步骤:构造表单-提交表单-获取返回信息

 

异步加载

 

#-*-coding:utf8-*-
import requests
import re
# url = 'https://www.crowdfunder.com/browse/deals'
url = 'https://www.crowdfunder.com/browse/deals&template=false'


# html = requests.get(url).text
# print html


#
注意这里的page后面跟的数字需要放到引号里面。
data = {
    'entities_only':'true',
    'page':'2'
}
html_post = requests.post(url,data=data)
title = re.findall('"card-title">(.*?)</div>',html_post.text,re.S)
for each in title:
    print each

 

2-4 实战-极客学院课程爬虫

  目标网站:http://www.jikexueyuan.com/course/

  目标内容:课程名称,课程介绍,课程时间,课程等级,学习人数

  涉及知识:         

    Requests获取网页

    re.sub换页

    正则表达式匹配内容

 

#-*_coding:utf8-*-
import requests
import re
import sys
reload(sys)
sys.setdefaultencoding("utf-8")#在windows下命令提示符默认的编码是GBK, 而网页是utf-8,将windows下命令提示符的编码方式强制转化为utf-8

class spider(object):
    def __init__(self):
        print u'开始爬取内容。。。'

#getsource用来获取网页源代码
   
def getsource(self,url):
        html = requests.get(url)
        return html.text

#changepage用来生产不同页数的链接
   
def changepage(self,url,total_page):
        now_page = int(re.search('pageNum=(\d+)',url,re.S).group(1))
        page_group = []
        for i inrange(now_page,total_page+1):
            link = re.sub('pageNum=\d+','pageNum=%s'%i,url,re.S)
            page_group.append(link)
        return page_group
#geteveryclass用来抓取每个课程块的信息
   
def geteveryclass(self,source):
        everyclass = re.findall('(<li deg="".*?</li>)',source,re.S)
        return everyclass
#getinfo用来从每个课程块中提取出我们需要的信息
   
def getinfo(self,eachclass):
        info = {}
        info['title'] =re.search('target="_blank">(.*?)</a>',eachclass,re.S).group(1)
        info['content'] = re.search('</h2><p>(.*?)</p>',eachclass,re.S).group(1)
        timeandlevel = re.findall('<em>(.*?)</em>',eachclass,re.S)
        info['classtime'] = timeandlevel[0]
        info['classlevel'] = timeandlevel[1]
        info['learnnum'] = re.search('"learn-number">(.*?)</em>',eachclass,re.S).group(1)
        return info
#saveinfo用来保存结果到info.txt文件中
   
def saveinfo(self,classinfo):
        f = open('info.txt','a')
        for each inclassinfo:
            f.writelines('title:' + each['title'] +'\n')
            f.writelines('content:' + each['content'] +'\n')
            f.writelines('classtime:' + each['classtime'] +'\n')
            f.writelines('classlevel:' + each['classlevel'] +'\n')
            f.writelines('learnnum:' + each['learnnum'] +'\n\n')
        f.close()

if __name__ == '__main__':

    classinfo = []
    url = 'http://www.jikexueyuan.com/course/?pageNum=1'
   
jikespider = spider()
    all_links = jikespider.changepage(url,20)
    for link inall_links:
        print u'正在处理页面:'+ link
        html = jikespider.getsource(link)
        everyclass = jikespider.geteveryclass(html)
        for each ineveryclass:
            info = jikespider.getinfo(each)
            classinfo.append(info)
    jikespider.saveinfo(classinfo)

 

课程总结

1)  requests获取网页源代码

2)  修改Http头绕过简单的反爬虫机制

3)  向网页提交内容

 

 

 


 

3、XPath 与多线程爬虫

3-1 XPath的介绍与配置

XPath – XML Path language

  XPath 是一门语言

  XPath可以在XML文档中查找信息

  XPath支持HTML

  XPath通过元素和属性进行导航

  XPath可以用来提取信息

  XPath比正则表达式厉害

  XPath比正则表达式简单

 

安装使用XPath

  安装lxml

  from lxmlimport etree

  Selector =etree.HTML(网页源代码)

  Selector.xpath(一段神奇的符号)

 

 

3-2 神器XPath的使用

XPath与HTML结构

 

获取网页元素的XPath

1)  手动分析法

2)  Chrome生成法 (右键对象 -> copyXPath)

 

XPath提取内容

  //定位根节点

  /往下层寻找

  提取文本内容:/text()

  提取属性内容: /@xxxx

 

 

3-3 XPath的特殊用法

以相同的字符开头

1)starts-with(@属性名称,属性字符相同部分)

 <div id="test-1">需要的内容1</div>

 <div id="test-2">需要的内容2</div>

 <divid="testfault">需要的内容3</div>

 

标签套标签

2) string(.)

 <div id=“class3”>美女,

             <font color=red>你的微信是多少?</font>

 </div>

3-4 python并行化介绍与演示

Python并行化介绍

  多个线程同时处理任务

  高效

  快速

 

 

map的使用

  map 函数一手包办了序列操作、参数传递和结果保存等一系列的操作。

  frommultiprocessing.dummy import Pool

  pool = Pool(4)            # 计算机有4个核

  results =pool.map(爬取函数,网址列表)

 

 

3-5 实战 – 百度贴吧爬虫

  目标网站:http://tieba.baidu.com/p/3522395718

  目标内容:跟帖用户名,跟帖内容,跟帖时间

  涉及知识:         

    Requests获取网页

    XPath提取内容

    map实现多线程爬虫

 

 

课程总结

  使用Xpath提取网页内容

  使用map实现多线程爬虫