背景简介

爬取外国的某两个网站的数据,网站都没有被墙,爬取三种数据。

  • A: 爬取页面并存储到数据库
  • B: 爬取页面内的表格内数据并存储到数据库
  • C: 爬取页面,分析页面并将页面的所有数据分类存入数据库,且页面内存在下级页面,也需要进行同样的操作

python包选取以及使用

连接链接

在windows电脑上编写调试代码,在linux服务器上运行代码

由于包的差异原因,根据系统选择了两种不同的连接方式(非最佳选择)

windows - urllib3

linux - pycurl、urllib(pycurl连接GET类型的链接时,需要使用urllib.parse对该链接的参数数据进行处理)

注:以下部分处理方法是经对该网站的所有测试,包括连接速度、连接时长、错误类型等进行尽量全面的测试之后采取的方法,不适用所有网站,需要酌情使用

urllib3

# method: 连接链接的方式-GET/POST
# url: 链接地址
# data: 连接链接时需要传输的参数数据 def getHtmlByLib(method, url, data):
try:
http = urllib3.PoolManager(timeout=1000) # 经测试得出:外国网站的连接速度由于时差原因会有不同的延迟,设置超时timeout为1000秒
r = http.request(method, url, fields=data)
html = r.data.decode("utf-8", "ignore") # 将网站页面源代码转换为utf-8时会报转换错误,衡量后使用 ignore 模式,会忽略转换错误的代码
return html
except:
return getHtmlByLib(method, url, data) # 在连接失败或其他错误发生时,重新连接该地址

pycurl

class htmlContents:
def __init__(self):
self.contents = ''
def callback(self, curl):
self.contents = self.contents + curl.decode("utf-8", "ignore") def getHtmlByCurl(method, url, data):
t = htmlContents()
curl = pycurl.Curl()
# 设置连接链接时的传输参数
if(len(data) > 0):
curl.setopt(pycurl.POSTFIELDS, urllib.parse.urlencode(data))
# 设置头部
headers = ["Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"]
curl.setopt(pycurl.HTTPHEADER, headers)
# 连接时长与curl的连接时长
curl.setopt(pycurl.CONNECTTIMEOUT, 1000)
curl.setopt(pycurl.TIMEOUT, 900)
# 传输速度 传输速度小于1字节/秒的状态持续90秒,该连接就会终止
curl.setopt(pycurl.LOW_SPEED_TIME, 90)
curl.setopt(pycurl.LOW_SPEED_LIMIT, 1)
# 连接成功以后的处理方法
curl.setopt(pycurl.WRITEFUNCTION, t.callback)
curl.setopt(pycurl.ENCODING, 'gzip, deflate')
curl.setopt(pycurl.URL, url)
# 设置连接以及下载速度的进度条展示
curl.setopt(pycurl.NOPROGRESS, 0)
# 把cookie保存在该文件中
# curl.setopt(pycurl.COOKIEFILE, "cookie_file_name")
# curl.setopt(pycurl.COOKIEJAR, "cookie_file_name")
# POST方式
if(method == "POST"):
curl.setopt(pycurl.POST, 1)
try:
curl.perform()
except pycurl.error as e:
curl.close()
return getHtmlByCurl(method, url, data)
# 获取HTTP_CODE
httpCode = curl.getinfo(curl.HTTP_CODE)
curl.close()
if(httpCode != 200):
return getHtmlByCurl(method, url, data)
# 页面内容
return t.contents

处理页面

bs4/json

bs4使用教程

爬取页面(A)

评价 : 比较简单,可以作为入门的爬虫,不是单纯的抓取页面,需要获取一些页面内的简单的数据。

使用bs4.BeautifulSoup进行页面数据的格式化

soup = BeautifulSoup(html, features="html.parser")

大略步骤如下

  1. 获取所有国家options = soup.find("select", id="country6").find_all("option")
  2. 根据国家ID连接链接获取报告列表,解析列表内数据,获取该国家每一年的每份报告的是否存在以及报告链接
  3. 连接报告链接获取页面源代码,并根据需求删除代码内节点树的某些节点
  4. 存入数据库

知识点

  1. BeautifulSoupfind_all()以及find()方法的使用

    • find_all() - 获取某个节点下的所有符合条件的节点,不单止子节点,而是所有子孙节点内符合条件的节点
    • find() - 获取左右子孙节点内第一个符合条件的节点
  2. BeautifulSoup的删除节点事件、删除节点

    • 删除节点事件

       divs = soup.find_all("div")
      for div in divs:
      if(div.has_attr('onmouseover')):
      del div["onmouseover"]
    • 删除节点 - div.decompose()

  3. BeautifulSoup输出页面源代码 - print(soup.prettify())

获取页面内的数据并处理(B)

爬取页面内的表格内数据并存储到数据库

评价:需求A的进阶型,主要针对选择页面内下拉列表的选项之后的请求的处理,主要处理json数据,需要对页面内JS方法的理解、在浏览器内使用开发者工具时的有效链接筛选

大略步骤如下:

  1. 获取第一个页面,解析页面源代码,了解后续操作所产生的JS事件以及影响,并通过浏览器开发者工具筛选出有效链接
  2. 连接第一步筛选出的有效链接,获取该链接传输来的json数据
  3. 获取最终目标链接所需要的传输参数。从第二步的json数据中获取;从第一部的初始页面获取;
  4. 连接目标链接,传输参数数据,并处理最终数据,存入数据库

知识点

  1. 该网站对连接次数做出了限制,会返回409状态码,并告知USAGE LIMIT: Hourly usage limit of 100 actions reached. You may resume use of this service at XXXX-XX-XXT03:43:10Z

    代码调整:1. 连接链接时设置休眠时间,time.sleep(10),可以减少409状态码的出现次数;2. 出现409状态码时,休眠10分钟time.sleep(60*10)

  2. 字符串转换为json

    import json
    jsonData = json.loads(data)

处理页面内所有数据并存储入数据库(C)

评价:由于该页面内容的多变性,数据处理方式需要更兼容,故认为为B需求的进阶型,基于B需求之后可以更容易筛选出有效链接,主要处理table内数据。

大略步骤如下:

  1. 获取第一个页面,获取页面内容并通过浏览器开发者工具筛选出有效链接
  2. 连接第一步筛选出的有效链接,获取页面内的table内容以及需要的数据,包括URL
  3. 连接table内的URL并获取页面源代码,使用BeautifulSoup对页面内容进行处理,获取需要的数据

知识点

  1. table的tr/td处理,子节点获取

    tableChoisir = soup.find("table", attrs={"class": "TableChoisir"})
    trsList = []
    for trChild in tableChoisir.children:
    # 子节点除了html节点以外,如换行、空白字符等也被视为子节点
    trChild = formatString(str(trChild))
    if len(trChild.strip(" ")) > 0:
    trSoup = bsHtml(trChild)
    trsList.append(trSoup)
  2. 获取节点内容

    title = trSoup.find("td", attrs={"class": "topbigtabletitle27"}).get_text()

总结叙述

  1. 使用bs4.BeautifulSoup可以很轻松的获取页面节点的所有内容
  2. pycurl的连接速度优于urllib3,同时也需要设置很多参数,pycurl可视为linux下的curl命令的封装,pycurl的参数设置可参考libcurl

python爬虫-爬坑之路的更多相关文章

  1. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  2. Vue 爬坑之路(六)—— 使用 Vuex + axios 发送请求

    Vue 原本有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource 目前主流的 Vue 项目,都选择 axios ...

  3. Vue 爬坑之路(九)—— 用正确的姿势封装组件

    迄今为止做的最大的 Vue 项目终于提交测试,天天加班的日子终于告一段落... 在开发过程中,结合 Vue 组件化的特性,开发通用组件是很基础且重要的工作 通用组件必须具备高性能.低耦合的特性 为了满 ...

  4. Python爬虫 - 爬取百度html代码前200行

    Python爬虫 - 爬取百度html代码前200行 - 改进版,  增加了对字符串的.strip()处理 源代码如下: # 改进版, 增加了 .strip()方法的使用 # coding=utf-8 ...

  5. Vue 爬坑之路(一)—— 使用 vue-cli 搭建项目

    vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目,GitHub地址是:https://github.com/vuejs/vue-cli vue ...

  6. Vue 爬坑之路(十二)—— vue-cli 3.x 搭建项目

    Vue Cli 3 官方文档:https://cli.vuejs.org/zh/guide/ 一.安装 @vue/cli 更新到 3.x 之后,vue-cli 的包名从 vue-cli 改成了 @vu ...

  7. 用Python爬虫爬取广州大学教务系统的成绩(内网访问)

    用Python爬虫爬取广州大学教务系统的成绩(内网访问) 在进行爬取前,首先要了解: 1.什么是CSS选择器? 每一条css样式定义由两部分组成,形式如下: [code] 选择器{样式} [/code ...

  8. 使用Python爬虫爬取网络美女图片

    代码地址如下:http://www.demodashi.com/demo/13500.html 准备工作 安装python3.6 略 安装requests库(用于请求静态页面) pip install ...

  9. Tinker爬坑之路

    目的 热修复去年年底出的时候,变成了今年最火的技术之一.依旧记得去年面试的时候统一的MVP,然而今年却变成了RN,热修复.这不得不导致我们需要随时掌握最新的技术.不然可能随时会被淘汰.记得刚进公司,技 ...

随机推荐

  1. 【原创】大叔经验分享(84)spark sql中设置hive.exec.max.dynamic.partitions无效

    spark 2.4 spark sql中执行 set hive.exec.max.dynamic.partitions=10000; 后再执行sql依然会报错: org.apache.hadoop.h ...

  2. GNU,GPL与自由软件

    GNU 是 Richard Stallman(理查德·斯托曼)创建的一个项目,not unix GPL(General Public License),GNU通用公共许可证.书面上的协议 自由软件与开 ...

  3. Spring IOC原理分析

    IOC IOC(Inversion of Control)控制反转:所谓的控制反转,就是把原先需要我们代码自己实现对象的创建和依赖,反转给容器来实现.那么必然Spring需要创建一个容器,同时需要创建 ...

  4. 五、HashMap的使用 及其源码解析

    HashMap的底层实现原理?领接表(数组+链表)hash表数组+链表+红黑树 链表:查找慢 插入 删除快红黑树:查找快 插入 删除慢 HashMap是线程安全的吗?不是线程安全的 在什么情况下 ,是 ...

  5. gitlab自动化部署CI案例

    参考: https://blog.csdn.net/hxpjava1/article/details/78514999   (简单操作) https://blog.csdn.net/wh211212/ ...

  6. Python使用selenium模拟点击,进入下一页(三)

    嗯,昨天呢,我们已经实现了自动输入百度然后搜索Cgrain,然后点击按钮,进入我的页面,在这里呢,有个问题 ActionChains(seleniumGoo).move_by_offset(-480, ...

  7. python-----多进程笔记

    多进程笔记: 在Python中多进程的创建方式对比: 1.在Python中,可以通过os.fork()创建子进程,但是这种方式智能在'linux'和'unix'以及'mac'下面使用,不能跨平台,所以 ...

  8. 用js刷剑指offer(跳台阶)

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 牛客网链接 思路 这一题和斐波那契数列思路完全一样. 假如青蛙从第n个 ...

  9. 学JAVA有哪些好的技巧方法?干货分享

    作为编程语言届的老大哥,学习JAVA的人数不胜数,在这里分享一些学习JAVA的技巧以及方法,当然,这些技巧及方法使用范围包含但不限于JAVA. ① 笔记软件 印象笔记:多端互通很方便(https:// ...

  10. cas的客户端配置

    知识点:cas的客户端配置 一:cas客户端配置 二:cas认证流程原理(图) 参考:https://www.cnblogs.com/suiyueqiannian/p/9359597.html 源码: ...