一、python简单爬取静态网页

一、简单爬虫框架

  简单爬虫框架由四个部分组成:URL管理器、网页下载器、网页解析器、调度器,还有应用这一部分,应用主要是NLP配合相关业务。

  它的基本逻辑是这样的:给定一个要访问的URL,获取这个html及内容(也可以获取head和cookie等其它信息),获取html中的某一类链接,如a标签的href属性。从这些链接中继续访问相应的html页面,然后获取这些html的固定标签的内容,并把这些内容保存下来。

  一些前提:;所有要爬取的页面,它们的标签格式都是相同的,可以写一个网页解析器去获取相应的内容;给定的URL(要访问的资源)所获得的html,它包含的标签链接是可以筛选的,筛选后的标签链接(新的URL)会被继续请求其html文档。调度器是一个循环体,循环处理这些URL、请求以及html、网页解析。

  1.运行流程

      

    调度器是一个主循环体,负责不断重复执行URL管理器、下载器、解析器。URL是管理新的URL的添加、旧的URL的去除,以及URL的去重和记录。下载器顾名思义,就是根据URL,发送http请求,获取utf-8编码的字节流的html文件数据。解析器负责将html还原成DOM对象,并提供一套类似js的DOM操作的方法,从html中获取节点、属性、文本、甚至是样式等内容。

  2.URL管理器

    URL管理器有两个功能,获取待添加的URL--判断它是否在已被读取的URL集合里--[No]判断它是否在待读取的URL集合里--[No]添加到待读取的URL集合里。否则就直接抛弃。

    URL管理器一般放在内存、关系型数据库和缓存数据库里。python里可以使用set()集合去重。

  3.网页下载器

    向给定的URL发送请求,获取html。python的两个模块。内置urllib模块和第三方模块request。python3将urllib2封装成了urllib.request模块。

 1 # 网页下载器代码示例
 2 import urllib
 3
 4 url = "http://www.baidu.com"
 5
 6 print("第一种方法: 直接访问url")
 7 response1 = urllib.request.urlopen(url)
 8 print(response1.getcode())  # 状态码
 9 print(len(response1.read()))  # read读取utf-8编码的字节流数据
10
11 print("第二种方法: 设置请求头,访问Url")
12 request = urllib.request.Request(url)  # 请求地址
13 request.add_header("user-agent", "mozilla/5.0")  # 修改请求头
14 response2 = urllib.request.urlopen(request)
15 print(response2.getcode())
16 print(len(response2.read()))
17
18 import http.cookiejar  # 不知道这是啥
19
20 print("第三种方法: 设置coockie,返回的cookie")
21 # 第三种方法的目的是为了获取浏览器的cookie内容
22 cj = http.cookiejar.CookieJar()
23 opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
24 urllib.request.install_opener(opener)
25 response3 = urllib.request.urlopen(url)
26 print(response3.getcode())
27 print(len(response3.read()))
28 print(cj)  # 查看cookie的内容

  4.网页解析器

    将utf-8编码的字节码重新重新解析为html。因为数据传输是字节数据,所以网页下载器下载的内容需要重新解析。

    提供DOM对象[html文档解构]的操作方法。和js类似。包括节点、标签元素、属性[包括name、class、style、value等等]、样式、内容等的操作。从而能够获取特定的内容。

    python的BeautifulSoup模块(bs4)。以下代码可直接在bs4模块官方文档中获取和运行。

 1 from bs4 import BeautifulSoup
 2 from re import compile
 3 html_doc = """
 4 <html><head><title>The Dormouse‘s story</title></head>
 5 <body>
 6 <p class="title"><b>The Dormouse‘s story</b></p>
 7
 8 <p class="story">Once upon a time there were three little sisters; and their names were
 9 <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
10 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
11 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
12 and they lived at the bottom of a well.</p>
13
14 <p class="story">...</p>
15 """
16
17 soup = BeautifulSoup(html_doc, "html.parser")
18 print(soup.prettify())
19 print(soup.title)
20 print(soup.title.name)
21 print(soup.title.string)
22 print(soup.title.parent.name)
23 print(soup.p)
24 print(soup.p[‘class‘])
25 print(soup.a)
26 print(soup.find_all(href=compile(r"/example.com/\S*")))
27 print(soup.find_all(‘a‘))
28 print(soup.find(id="link3"))
29 print(soup.get_text())
30 print(soup.find("p", attrs={"class": "story"}).get_text())
31
32 for link in soup.find_all(‘a‘):
33     print(link.get(‘href‘))

二、简单示例

  爬取百度百科上词条为python的以href=‘/tem/‘开头的所有相关网页的词条简介。

  1 from re import compile
  2 from html.parser import HTMLParser
  3 from bs4 import
  4
  5 # url管理器
  6 class UrlManager(object):
  7     """
  8     url管理器主要有三个功能:add_new_url添加新的待爬取的页面;get_new_url删除已爬取的页面;标记待爬取的和已爬取的页面。
  9     """
 10     def __init__(self):
 11         self.new_urls = set()
 12         self.old_urls = set()
 13     def add_new_url(self, url):
 14         if url is None:
 15             return
 16         # 如果传入的url既不在待爬取的url里又不在爬过的url里,说明它是待爬取的url
 17         if url not in self.new_urls and url not in self.old_urls:
 18             self.new_urls.add(url)
 19
 20     def add_new_urls(self, urls):
 21         if urls is None or len(urls) == 0:
 22             return
 23         for url in urls:
 24             self.add_new_url(url)
 25
 26     def has_new_url(self):
 27         return len(self.new_urls) != 0
 28
 29     def get_new_url(self):
 30         new_url = self.new_urls.pop()  # 从待爬去的url中剔除要爬取的目标
 31         self.old_urls.add(new_url)     # 添加到
 32         return new_url
 33
 34 # 简单的下载器
 35 class HtmlDownloader(object):
 36     def download(self, url):
 37         if url is None:
 38             return None
 39         response = urllib.request.urlopen(url)
 40         if response.getcode() != 200:
 41             return None
 42         return response.read()
 43
 44 # 解析器
 45 class HtmlParser(object):
 46     def _get_new_urls(self, page_url, soup):
 47         # 这里要提一下,百度百科python词汇的url是https://baike.baidu.com/item/Python/407313
 48         # 页面中的a标签的href属性都类似href="/item/%E6%95%99%E5%AD%A6"这种属性
 49         # 在处理时,需要加上baike.baidu.com保证url资源定位符的完整性。后面只需匹配"/item/"
 50         new_urls = set()
 51         links = soup.find_all(‘a‘, href=compile(r"/item/\S*"))
 52         for link in links:
 53             new_url = link["href"]
 54             new_full_url = urllib.parse.urljoin(page_url, new_url)
 55             new_urls.add(new_full_url)
 56         return new_urls
 57
 58     def _get_new_data(self, page_url, soup):
 59         res_data = {}
 60         res_data["url"] = page_url
 61         # 爬取标题
 62         # <dd class="lemmaWgt-lemmaTitle-title"></dd><h1>Python</h1>
 63         title_node = soup.find("dd", attrs={"class": "lemmaWgt-lemmaTitle-title"}).find("h1")
 64         res_data["title"] = title_node.get_text()
 65         # 爬取简介内容
 66         # <div class="lemma-summary" label-module="lemmaSummary"></div>
 67         # 这个div下的所有div里的text
 68         summary_node = soup.find(‘div‘, attrs={"class": "lemma-summary", "label-module":"lemmaSummary"})
 69         res_data["summary"] = summary_node.get_text()
 70         return res_data
 71
 72     def parse(self, page_url, html_doc):
 73         if page_url is None or html_doc is None:
 74             return
 75         # 解析成了一个整个的DOM对象,也就是纯html格式的文件
 76         soup = BeautifulSoup(html_doc, "html.parser", from_encoding="utf-8")
 77         new_urls = self._get_new_urls(page_url, soup)
 78         new_data = self._get_new_data(page_url, soup)
 79         # print("page_url: %r, new_urls: %r, new_data: %r" % (page_url, new_urls, new_data))
 80         return new_urls, new_data
 81
 82 # 输出器
 83 class HtmlOutputer(object):
 84     def __init__(self):
 85         self.datas = []
 86     def collect_data(self, data):
 87         if data is None:
 88             return
 89         self.datas.append(data)
 90     def output_html(self):
 91         fout = open("output.html", ‘w‘, encoding="UTF-8")
 92         fout.write("<html>")
 93         fout.write("<meta http-equiv=‘content-type‘ content=‘text/html;charset=utf-8‘>")
 94         fout.write("<body>")
 95         fout.write("<table>")
 96         for data in self.datas:
 97             fout.write("<tr>")
 98             fout.write("<td>%s</td>" %data[‘url‘])
 99             fout.write("<td>%s</td>" %data[‘title‘])
100             fout.write("<td>%s</td>" %data[‘summary‘])
101             fout.write("</tr>")
102         fout.write("</table>")
103         fout.write("</body>")
104         fout.write("</html>")
105
106 class SpiderMain(object):
107     def __init__(self):
108         self.urls = UrlManager()
109         self.downloader = HtmlDownloader()
110         self.parser = HtmlParser()
111         self.outputer = HtmlOutputer()
112
113     def craw(self, root_url):
114         count = 1
115         self.urls.add_new_url(root_url)
116         while self.urls.has_new_url():
117             try:
118                 new_url = self.urls.get_new_url()
119                 html_cont = self.downloader.download(new_url)
120                 # print("\033[1;36m %r \033[0m" % html_cont.decode("utf-8"))
121                 new_urls, new_data = self.parser.parse(new_url, html_cont)
122                 self.urls.add_new_urls(new_urls)
123                 self.outputer.collect_data(new_data)
124                 if count == 11:break
125                 print("\033[1;36m [CRAW]\033[0m :  %d %r" %(count, new_url))
126                 count += 1
127             except Exception as e:
128                 print("craw failed")
129                 print(e)
130         self.outputer.output_html()

    运行结果如下:

    打开保存的out.html,内容如下:

原文地址:https://www.cnblogs.com/kuaizifeng/p/8845891.html

时间: 2024-10-06 00:03:44

一、python简单爬取静态网页的相关文章

Python开发简单爬虫之静态网页抓取篇:爬取“豆瓣电影 Top 250”电影数据

目标:爬取豆瓣电影TOP250的所有电影名称,网址为:https://movie.douban.com/top250 1)确定目标网站的请求头: 打开目标网站,在网页空白处点击鼠标右键,选择"检查".(小编使用的是谷歌浏览器). 点击"network",在弹出页面若长时间没有数据显示,则试一下F5刷新. 可以得到目标网页中Host和User-Agent两项. 2)找到爬取目标数据(即电影名称)在页面中的位置 右键"检查",选择"Elem

python之爬取网页数据总结(一)

今天尝试使用python,爬取网页数据.因为python是新安装好的,所以要正常运行爬取数据的代码需要提前安装插件.分别为requests    Beautifulsoup4   lxml  三个插件. 因为配置了环境变量,可以cmd命令直接安装.假如电脑上有两个版本的python,建议进入到目录安装. 安装的命令为 pip install requests(Beautifulsoup4   /lxml  ) 三条分别执行. 安装结束,可以尝试网上一些简单的例子,明白了解 Beautifulso

python爬取动态网页

静态网页:根据url即可方便的爬取 动态网页:分为两种:一种是通过F12查看控制台的xhr等文件,找到包含所要爬取的内容的文件,发现这个文件的url路径跟页码有联系,那么就可以根据构造的url来进行访问爬取了.还有一种情况是查看了包含所要爬取内容的文件,发现文件url是固定不变的或者跟页码没有关系,这个时候可以通过简单的模拟浏览器点击行为来请求网页再爬取,这种方案执行效率较慢,不适于多页爬取的情况.代码如下: 1 def parse(self, response): 2 print 'parse

python爬取某个网页的图片-如百度贴吧

python爬取某个网页的图片-如百度贴吧 作者:vpoet 日期:大约在冬季 注:随意copy,不用告诉我 #coding:utf-8 import urllib import urllib2 import re if __name__ =="__main__": rex=r'src="(http://imgsrc.baidu.com/forum/w%3D580.*?\.jpg)"'; Response=urllib2.urlopen("http://t

python——关于简单爬取博客园班级成员发的博文的题目、发布人、阅读、评论,再存到csv文件中

因为老师要以班里每个人发的博客质量作为最后总成绩的评定的一部分,就要把班上所有同学发的博客都统计起来,可以用来评定的因素有:阅读.评论.推荐等,但因为今天只是做一个简单的爬取,推荐这个元素在班级博客中需要点开每一篇博文才能看到获取,就不爬取了,只爬取阅读和推荐,加上每篇博文的发布人和标题. 我先会放上代码,再逐条解释其含义及作用. 代码如下(其中爬取的网页是以我自己的班级为例): 1 from bs4 import BeautifulSoup 2 import pandas as pd 3 im

python爬虫——爬取网页数据和解析数据

1.网络爬虫的基本概念 网络爬虫(又称网络蜘蛛,机器人),就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序.只要浏览器能够做的事情,原则上,爬虫都能够做到. 2.网络爬虫的功能   图2 网络爬虫可以代替手工做很多事情,比如可以用于做搜索引擎,也可以爬取网站上面的图片,比如有些朋友将某些网站上的图片全部爬取下来,集中进行浏览,同时,网络爬虫也可以用于金融投资领域,比如可以自动爬取一些金融信息,并进行投资分析等. 有时,我们比较喜欢的新闻网站可能有几个,每次

python scrapy爬取动态页面

preface:最近学习工作之外,有个异性朋友需要爬取动态网页的要求,输入关键词爬取某个专利网站在该关键词下的一些专利说明.以往直接python urllib2可破,但是那只是对于静态网页可破,但是对于用js等其他的生成的动态网页的话,则貌似不行(没试过).然后在网上找了些资料,发现scrapy结合selenium包好像可以.(之所以这么说,暂时卤主也还没实现,先记录下来.) #=====================根据官网中简单的介绍作个人理解=======================

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

用Python爬虫爬取广州大学教务系统的成绩(内网访问) 在进行爬取前,首先要了解: 1.什么是CSS选择器? 每一条css样式定义由两部分组成,形式如下: [code] 选择器{样式} [/code] 在{}之前的部分就是"选择器"."选择器"指明了{}中的"样式"的作用对象,也就是"样式"作用于网页中的哪些元素.可参考:http://www.w3school.com.cn/cssref/css_selectors.asph

python爬虫--爬取某网站电影下载地址

前言:因为自己还是python世界的一名小学生,还有很多路要走,所以本文以目的为向导,达到目的即可,对于那些我自己都没弄懂的原理,不做去做过多解释,以免误人子弟,大家可以网上搜索. 友情提示:本代码用到的网址仅供交流学习使用,如有不妥,请联系删除. 背景:自己有台电脑要给老爸用,老爷子喜欢看一些大片,但是家里网络环境不好,就想批量下载一些存到电脑里.但是目前大部分的网站都是这样的, 需要一个个地点进去,才能看到下载地址 如果我要下载100部电影,那肯定手都要点断了,于是便想把这些地址给爬取出来,