Spider(一)——爬虫基础

一、网络爬虫

     1、定义 :网络蜘蛛、网络机器人,抓取网络数据的程序
     2、总结 :用Python程序去模仿人去访问网站,模仿的越像人越好
     3、爬取数据的目的 :通过有效的大量数据分析市场走势、公司决策

二、企业获取数据的方式

     1、公司自有数据
     2、第三方数据平台购买
       数据堂、贵阳大数据交易所
     3、爬虫爬取数据
       市场上没有或者价格太高,利用爬虫程序爬取

三、Python做爬虫优势

     请求模块、解析模块丰富成熟,强大的scrapy框架
     PHP   :对多线程、异步支持不太好
     JAVA  :代码笨重,代码量很大
     C/C++ :虽然效率高,但是代码成型很慢

四、爬虫分类

     1、通用网络爬虫(搜索引擎引用,需要遵守robots协议)
       http://www.taobao.com/robots.txt
       搜索引擎如何获取一个新网站的URL
             1、网站主动向搜索引擎提供(百度站长平台)
             2、和DNS服务网(万网)合作,快速收录新网站
     2、聚焦网络爬虫
       自己写的爬虫程序:面向主题的爬虫、面向需求的爬虫

五、爬取数据的步骤

     1、确定需要爬取的URL地址
     2、通过HTTP/HTTPS协议来获取相应的HTML页面
     3、提取HTML页面中有用的数据
       1、所需数据,保存
       2、页面中有其他的URL,继续 第2步

六、Anaconda和Spyder

     1、Anaconda :开源的Python发行版本
     2、Spyder :集成开发环境
       Spyder常用快捷键:
         1、注释/取消注释 :ctrl + 1
         2、保存 :ctrl + s
         3、运行程序 :F5
         4、自动补全 :Tab

七、Chrome浏览器插件

1、安装步骤

  1、浏览器右上角 - 更多工具 - 扩展程序
  2、点开右上角 - 开发者模式(打开)
  3、把插件 拖拽到 浏览器页面,释放鼠标,点击 添加扩展...

2、插件介绍

  1、Xpath Helper :网页数据解析插件
  2、JSON View    :查看json格式的数据(好看)
  3、Proxy SwitchOmega :代理切换插件

八、Fiddler抓包工具

1、抓包工具设置

     1、Tools->options->HTTPS->...from browers only
     2、connections :设置端口号 8888

2、设置浏览器代理

     Proxy SwitchOmega -> 选项 -> 新建情景模式 -> HTTP 127.0.0.1 8888 -> 应用选项

     浏览器右上角图标 -> AID1807 -> 访问百度

九、WEB

1、HTTP和HTTS

     1、HTTP :端口80(默认)
     2、HTTPS :端口443,HTTP的升级版,加了一个安全套接层

2、GET和POST

     1、GET :查询参数都会在URL地址上显示出来
     2、POST:查询参数和需要提交数据是隐藏在Form表单里的,不会再URL地址上显示

3、URL :统一资源定位符

     https:// item.jd.com  :80/443      /11963238.html   #detail

     协议     域名/IP地址  端口(省略)  访问资源的路径   锚点(可省略)

4、User-Agent

     记录用户的浏览器、操作系统等,为了让用户获取更好的HTML页面效果
     ex:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
     内核:
         Mozilla Firefox :(Gecko内核) -(自己的内核)
         IE :Trident(自己的内核)
         Linux : KTHML(like Gecko)
         Apple :Webkit(like KHTML)
         Google:Chrome(like Webkit)
         其他浏览器都是模仿IE/Chrome

     常见 User-Agent 大全
     偶然发现一个比自己手动切换user_agent更好的方法:传送门————修改于2019_08_30。

十、爬虫请求模块

1、版本

     1、python2 :urllib2、urllib
     2、python3 :把urllib和urllib2合并,urllib.request

2、python3常用方法(url.request

     1、urllib.request.urlopen("网址")
         1、作用 :向网站发起一个请求,并获取响应
             字节流 = response.read()
             字符串 = response.read().decode("utf-8")
             encode() : 字符串 --> bytes
             decode() : bytes  --> 字符串(解码)

import urllib.request

# 向百度发起请求,并得到响应对象
# urllib /... 
response = urllib.request.urlopen("http://www.baidu.com/")
# 打印响应内容
print(response.read().decode("utf-8"))


#decode() : bytes -> string
#encode() : string -> bytes
01_urlopen示例.py

         2、重构User-Agent
             1、不支持重构User-Agent:
                 urllib.request.urlopen()
             2、支持重构User-Agent:
                 urllib.request.Request(添加User-Agent)
     2、urllib.request.Request("url",headers={"User..})
         User-Agent是爬虫和反爬虫斗争的第一步,发送请求必须带User-Agent
         1、使用流程(见 02_urllib.request.Request.py)
             1、创建请求对象:利用Request()方法
             2、获取响应对象:利用urlopen(请求对象)
             3、获取响应内容:利用响应对象的read().decode("utf-8")获取内容
                     html=response.read().decode("utf-8")
         2、响应对象response的方法
             1、read() :读取服务器响应的内容(字节流)
             2、getcode()
                 作用:返回HTTP的响应码
                 print(respones.getcode())
                 200 :成功
                 4XX :服务器页面出错
                 5XX :服务器出错
             3、geturl()
                 作用:返回实际数据的URL(防止重定向问题)
                 print(respones.geturl())

import urllib.request

# 创建请求对象(Request,把User-Agent加在里面)
url = "http://www.baidu.com/"
headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"}
req = urllib.request.Request(url,headers=headers)
# 获取响应对象 urlopen(请求对象)
res = urllib.request.urlopen(req)
# 获取响应内容
html = res.read().decode("utf-8")
#print(html)

# getcode()
print(res.getcode())
# geturl()
print(res.geturl())
02_Request.py

3、urllib.parse模块

用于encode转码操作

      1、urllib.parse.urlencode("字典")
           编码前 :urlencode({"wd":"帅哥"})
           编码后 :wd=%e5%b8%85%e5%93%a5
           tedu = {"wd":"达内科技"}
           示例见 :03_urlencode.py
               请输入你要搜索的内容:美女
               保存到本地文件 :美女.html

import urllib.request
import urllib.parse

# 拼接URL
baseurl = "http://www.baidu.com/s?"
key = input("请输入要搜索的内容:")
key = urllib.parse.urlencode({"wd":key})
# key : "wd=%e8%a3%e6..."
url = baseurl + key

# 创建请求对象
headers = {"User-Agent":"Mozilla/5.0"}
req = urllib.request.Request(url,headers=headers)
# 获取响应对象
res = urllib.request.urlopen(req)
# 获取响应内容
html = res.read().decode("utf-8")

# 保存到本地文件 :百度.html
with open("百度.html","w",encoding="gb18030") as f:
    f.write(html)
03_urlencode.py

           注意:
               1、urlencode的参数一定要为 字典,得到的结果为 字符串
               2、with open("Baidu.html","w",encoding="utf-8") as f:
                      f.write(html)   # 保存到本地文件:百度.html
      2、urllib.parse.quote("字符串") 见 04_quote.py
           1、http://www.baidu.com/s?wd=帅哥
           2、key = urllib.parse.quote("帅哥")
            key的值 :"%e8%a3%b4..."

import urllib.request
import urllib.parse

# 拼接URL
baseurl = "http://www.baidu.com/s?wd="
key = input("请输入要搜索的内容:")
key = urllib.parse.quote(key)
# key : "%e8%a3%e6..."
url = baseurl + key

# 创建请求对象
headers = {"User-Agent":"Mozilla/5.0"}
req = urllib.request.Request(url,headers=headers)
# 获取响应对象
res = urllib.request.urlopen(req)
# 获取响应内容
html = res.read().decode("utf-8")

# 保存到本地文件 :百度.html
with open("百度.html","w",encoding="gb18030") as f:
    f.write(html)
    print("保存成功")
04_quote.py

      3、urllib.parse.unquote("字符串")
           s = "%d3%e8..."
           s = urllib.parse.unquote(s)  #得到解码之后的字符串

4、练习

       百度贴吧数据抓取
       要求:
             1、输入要抓取的贴吧名称
             2、输入爬取的起始页和终止页
             3、把每一页的内容保存到本地
           第1页.html 第2页.html ... ...
       步骤:
             1、找URL规律,拼接URL
             第1页:http://tieba.baidu.com/f?kw=??&pn=0
             第2页:http://tieba.baidu.com/f?kw=??&pn=50
             第3页:http://tieba.baidu.com/f?kw=??&pn=100
             .....
             第n页:pn=(n-1)*50
             2、获取网页内容(发请求获响应)
             3、保存(本地文件、数据库)

import urllib.request
import urllib.parse
import random
import time

# 接收用户输入
name = input("请输入贴吧名称:")
begin = int(input("请输入起始页:"))
end = int(input("请输入终止页:"))
# 拼接URL,发请求
baseurl = "http://tieba.baidu.com/f?"
h_list = [
          {"User-Agent":"Mozilla/5.0"},
          {"User-Agent":"Mozilla/4.0"},
          {"User-Agent":"Mozilla/3.0"},
    ]
headers = random.choice(h_list)
# url编码
key = {"kw":name}
key = urllib.parse.urlencode(key)

for page in range(begin,end+1):
    pn = (page-1)*50
    url = baseurl + key + "&pn=" + str(pn)
    # 发请求/得响应
    req = urllib.request.Request(url,headers=headers)
    res = urllib.request.urlopen(req)
    print("正在爬取第%d页" % page)
    html = res.read().decode("utf-8")
    time.sleep(0.5)
    
    # 写入本地文件
    filename = "" + str(page) + "页.html"
    with open(filename,"w",encoding="gb18030") as f:
        f.write(html)
        print("第%d页爬取成功" % page)
        print("*" * 30)
05_百度贴吧.py
import urllib.request
import urllib.parse

class BaiduSpider:
    def __init__(self):
        self.baseurl = "http://tieba.baidu.com/f?"
        self.headers = {"User-Agent":""}
    
    # 请求并获取页面内容
    def getPage(self,url):
        req = urllib.request.Request(url,headers=self.headers)
        res = urllib.request.urlopen(req) 
        html = res.read().decode("utf-8")
        return html

    # 保存
    def writePage(self,filename,html):
        with open(filename,"w",encoding="utf-8") as f:
            f.write(html)
    
    # 主函数
    def workOn(self):
        name = input("请输入贴吧名称:")
        begin = int(input("请输入起始页:"))
        end = int(input("请输入终止页:"))
        # url编码
        key = {"kw":name}
        key = urllib.parse.urlencode(key)

        for page in range(begin,end+1):
            pn = (page-1)*50
            url = self.baseurl + key + "&pn=" + str(pn)
            html = self.getPage(url)
            filename = ""+str(page)+"页.html"
            self.writePage(filename,html)
            
if __name__ == "__main__":
    # 创建对象
    spider = BaiduSpider()
    spider.workOn()
06_百度贴吧class.py

十一、请求方式及实例

1、GET

     1、特点 :查询参数在URL地址中显示
     2、案例 :抓取百度贴吧

2、POST (在Request方法中添加data参数)

     1、req = urllib.request.Request(url,data=data,headers=headers)
          data:表单数据以bytes类型提交,不能是string
     2、处理表单数据为bytes类型
          1、把Form表单数据定义为字典data
          2、urlencode(data)
          3、转为bytes数据类型 :bytes()
     3、案例 :有道翻译
         1、要求
         用户输入需要翻译的内容,把翻译的结果给输出来
         http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule
     4、有道翻译返回的是json格式的字符串,如何把json格式的字符串转换为Python中字典
           import json
           s = '{"key":"value"}'
           s_dict = json.loads(s)

           字典 = json.loads(json格式的字符串)

import urllib.request
import urllib.parse
import json

# 接收用户输入,对 data 进行转码(字节流)
key = input("请输入要翻译的内容:")
data = {
        "i":key,
        "from":"AUTO",
        "to":"AUTO",
        "smartresult":"dict",
        "client":"fanyideskweb",
        "salt":"1542876206627",
        "sign":"6903dad5191ed03cdc87868f0ef748dc",
        "doctype":"json",
        "version":"2.1",
        "keyfrom":"fanyi.web",
        "action":"FY_BY_REALTIME",
        "typoResult":"false"
    }

#1、把Form表单数据整理成字典
#2、urlencode(字典) -> 字符串,字符串.encode("utf-8") -> 字节流
data = urllib.parse.urlencode(data).encode("utf-8")
# 发请求,获响应
url = "http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule"
headers = {"User-Agent":"Mozilla/5.0"}

req = urllib.request.Request(url,data=data,headers=headers)
res = urllib.request.urlopen(req)
html = res.read().decode("utf-8")
# html为json格式的字符串
r_dict = json.loads(html)
#print(type(r_dict))
print(r_dict["translateResult"][0][0]["tgt"])


#{'type': 'EN2ZH_CN', 
# 'errorCode': 0, 
# 'elapsedTime': 1, 
# 'translateResult': 
#[[{'src': 'hello', 'tgt': '你好'}]]
#}
07_有道翻译POST.py

 

posted on 2018-11-24 16:33  破天荒的谎言、谈敷衍  阅读(1473)  评论(0)    收藏  举报

导航