python3轻量级爬虫

为什么是轻量级爬虫?因为复杂的爬虫需要考虑的场景和问题非常的多,比如有些网页需要登录后才能访问、而有些网页使用javascript异步加载完成。轻量级爬虫爬取的是不需要登录的静态网页抓取。

一.爬虫简介

  • 爬虫是一段自动抓取互联网信息的程序,从一个url触发访问所关联的所有url,并且从每个页面中提取出有价值的数据。
  • 价值:互联网数据,为我所用。可以对数据进行分析,甚至可以基于数据做出自己的产品,比如更专业的新闻阅读聚合器,最爆笑故事app,最漂亮美女图片网,图书对比价格网,python技术文章大全。

二.简单爬虫架构

首先需要一个爬虫调度端,来启动爬虫、停止爬虫、或者监视爬虫的运行情况。在爬虫架构中有三个模块:

  • URL管理器:将要爬取的URL和已经爬取过的URL
  • 网页下载器:将网页下载下来存储成一个字符串
  • 网页解析器:解析字符串,一方面提取有价值的数据,另一方面提取访问其他页面的URL
调度器 URL管理器 下载器 解析器 应用 有待爬URL? 是/否 获取1个待爬取URL URL 下载URL内容 URL内容 解析URL内容 价值数据、新URL列表 收集价值数据 新增到待爬取URL loop [ 有待爬取URL? ] 调度器 URL管理器 下载器 解析器 应用

三.URL管理器

管理待抓取URL集合和已抓取URL集合,防止重复抓取、循环抓取。

3.1 url管理器应具有的最小功能:

  • 添加新url到待爬取集合
  • 判断待添加url是否在容器中
  • 判断是否还有待爬取url
  • 获取待爬取url
  • 将url从待爬取移动到已爬取

3.2 实现方式

  • 放在内存中set()集合。待爬取set(),已爬取set()
  • 存放在关系数据库中urls(url,is_crawled)
  • 存放在缓存数据库中,比如redis,本身支持set数据结构。大公司一般都使用缓存数据库

四.网页下载器

将互联网上URL对应的网页下载到本地的工具

  • urllib.request:直接的网页下载,或者提交一些向网业输入的数据,甚至支持需要登录网页的cookie处理,需要代理访问的代理处理等。
  • requests:第三方包,提供更强大的功能

4.1 urllib简单的获取一个网页。

爬取百度首页就出错。。。试了几种方法,只有(‘gbk’,‘ignore’)有用,并且是偶尔正常显示。爬取其他网页就很顺利,不知道是百度厉害,还是代码太low。最终解决,在第一行添加如下代码即可。。。不过也是是好是坏。


# -*- coding: UTF-8 -*- 
或
#coding=utf-8
  1. urlopen()参数
    • url: 需要打开的网址
    • data:Post提交的数据
    • timeout:设置网站的访问超时时间,单位秒
  2. urlopen返回对象提供方法:
    • read() , readline() ,readlines() , fileno() , close() :对HTTPResponse类型数据进行操作
    • info():返回HTTPMessage对象,表示远程服务器返回的头信息
    • getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
    • geturl():返回请求的url

4.2 使用Request

  • 用来包装头部的数据:
    • User-Agent :这个头部可以携带如下几条信息:浏览器名和版本号、操作系统名和版本号、默认语言
    • Referer:可以用来防止盗链,有一些网站图片显示来源http://***.com,就是检查Referer来鉴定的
    • Connection:表示连接状态,记录Session的状态。

4.3 添加特殊情景的处理

HTTPCookieProcessor,ProxyHandler,HTTPHandler,HTTPRedirectHandler生成handler

# -*- coding: UTF-8 -*-
import urllib.request
from http import cookiejar

url = "http://www.baidu.com"
print("第一种方法")
response1 = urllib.request.urlopen(url)
print(response1.getcode())
print(len(response1.read()))

print("第二种方法")
request=urllib.request.Request(url)
request.add_header("user-agent","Mozilla/5.0")
response2=urllib.request.urlopen(request)
print(response2.getcode())
print (len(response2.read()))


print("第三种方法")
cj=cookiejar.CookieJar()
opener=urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
urllib.request.install_opener(opener)
response3=urllib.request.urlopen(url)
print(response3.getcode())
print(cj)
print(response3.read())

五.网页解析器

从网页中提取有价值的数据的工具

  • 正则表达式,字符串匹配的模糊匹配,比较直观,但是麻烦
  • html.parser自带
  • Beautifulsoup插件,结构化解析-DOM树
  • lxml插件

5.1 安装beautifulsoup4

可以import bs4即安装成功。查看官方文档

5.2 beautifulsoup语法

创建Beautifulsoup对象,搜索节点find_all、find(参数一样),访问节点名称、属性、文字

例如:
<a href='123.html' class='article_link'>python</a>

节点名称:a
节点属性:href='123.html' class='article_link'
节点内容:python

#创建
soup = BeautifulSoup(html_cont, 'html.parser',from_encoding='utf-8')


#查找节点a
soup.find_all('a')
#查找节点a,链接符合/view/123.html形式的节点
soup.find_all('a',herf='/view/123.html')
soup.find_all('a',herf=re.compile(r'/view/\d+\.html'))#可以用正则表达式替代
#查找节点div,class为abc,文字为python的节点
node = soup.find_all('div',class_='abc', string='python')

#访问节点信息
node.name #标签名称
node['href'] #标签属性
node.get_text() #文字内容

5.3 示例代码:

# coding=utf8
from bs4 import BeautifulSoup
import re

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""

soup = BeautifulSoup(html_doc, 'html.parser')
print("打印所有内容")
links = soup.find_all('a')
for link in links:
    print(link.name, link['href'], link.get_text())

print("获取lacie的连接")
link_node = soup.find('a',href="http://example.com/lacie")
print(link_node.name, link_node['href'], link_node.get_text())

print("正则匹配")
link_node = soup.find('a',href=re.compile(r"ill"))
print(link_node.name, link_node['href'], link_node.get_text())

print("获取段落文字")
p_node = soup.find('p',class_="title")
print(p_node.name, p_node.get_text())

六.完整实例

  • 目标:抓取百度百科Python词条相关的1000条页面数据。
  • 分析目标:URL格式,数据格式,网页编码
  • 编写代码
  • 最后执行爬虫

6.1 分析目标

- 目标:百度百科python词条相关词条网页-标题和简介
- 入口页:https://baike.baidu.com/item/Python/407313
- url格式:/item/接口/15422203
- 数据格式:
    - 标题 <dd class="lemmaWgt-lemmaTitle-title"><h1>...</h1>...</dd>
    - 简介 <div class="lemma-summary" label-module="lemmaSummary">...</div>
- 页面编码:UTF-8

查看代码
打包下载

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Gecco是什么 Gecco是一款用java语言开发的轻量化的易用的网络爬虫。Gecco整合了jsoup、httpclient、fastjson、spring、htmlunit、redission等优秀框架,让您只需要配置一些jquery风格的选择器就能很快的写出一个爬虫。Gecco框架有优秀的可扩展性,框架基于开闭原则进行设计,对修改关闭、对扩展开放。同时Gecco基于十分开放的MIT开源协议,无论你是使用者还是希望共同完善Gecco的开发者,欢迎pull request。如果你喜欢这款爬虫框架请star 或者 fork!参考手册架构图: 主要特征  简单易用,使用jquery风格的选择器抽取元素  支持页面中的异步ajax请求  支持页面中的javascript变量抽取  利用Redis实现分布式抓取,参考gecco-redis  支持结合Spring开发业务逻辑,参考gecco-spring  支持htmlunit扩展,参考gecco-htmlunit  支持插件扩展机制  支持下载时UserAgent随机选取  支持下载代理服务器随机选取 使用手册:http://www.geccocrawler.com/tag/sysc/快速入门:@Gecco(matchUrl="https://github.com/{user}/{project}", pipelines="consolePipeline") public class MyGithub implements HtmlBean {     private static final long serialVersionUID = -7127412585200687225L;     @RequestParameter("user")     private String user;     @RequestParameter("project")     private String project;     @Text     @HtmlField(cssPath=".repository-meta-content")     private String title;     @Text     @HtmlField(cssPath=".pagehead-actions li:nth-child(2) .social-count")     private int star;     @Text     @HtmlField(cssPath=".pagehead-actions li:nth-child(3) .social-count")     private int fork;     @Html     @HtmlField(cssPath=".entry-content")     private String readme;     public String getReadme() {         return readme;     }     public void setReadme(String readme) {         this.readme = readme;     }     public String getUser() {         return user;     }     public void setUser(String user) {         this.user = user;     }     public String getProject() {         return project;     }     public void setProject(String project) {         this.project = project;     }     public String getTitle() {         return title;     }     public void setTitle(String title) {         this.title = title;     }     public int getStar() {         return star;     }     public void setStar(int star) {         this.star = star;     }     public int getFork() {         return fork;     }     public void setFork(int fork) {         this.fork = fork;     }     public static void main(String[] args) {         GeccoEngine.create()         .classpath("com.geccocrawler.gecco.demo")         .start("https://github.com/xtuhcy/gecco")         .thread(1)         .interval(2000)         .loop(true)         .mobile(false)         .start();     } }demo地址:教您使用java爬虫gecco抓取JD全部商品信息(一)教您使用java爬虫gecco抓取JD全部商品信息(二)教您使用java爬虫gecco抓取JD全部商品信息(三)集成Htmlunit下载页面爬虫的监控一个完整的例子,分页处理,结合spring,mysql入库 标签:网络爬虫  开源爬虫
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值