汇总:python网络爬虫-采集整个网站

优采云 发布时间: 2022-12-21 11:20

  汇总:python网络爬虫-采集整个网站

  上文章实现了在一个网站上随机跳转到另一个链接。 但是,如果你需要系统地按类别对整个网站进行分类,或者搜索网站的每个页面,你必须采集整个网站,这是一个非常耗费内存的过程,尤其是在处理大型网站时,最适合的工具就是用一个数据库来存储采集的资源。

  1. 深网和暗网

  您可能听说过深层网络、暗网或隐藏网络等术语,尤其是在最近的媒体中。 他们的意思是什么? 深层网络是与表面网络相对的网络部分。 浅层网络是搜索引擎可以抓取的 Internet 部分。 据不完全统计,大约90%的互联网实际上是深网。 因为谷歌不能做表单提交之类的事情,不能找到没有直接链接到顶级域的页面,或者因为被robots.txt禁止而不能查看网站,所以浅层网络的数量相对与深网相比较小。 .

  暗网,又称暗网或暗网,完全是另一种怪物。 他们也建立在现有网络上,但使用 Tor 客户端,以及在 HTTP 之上运行的新协议,为信息交换提供安全隧道。 这些黑暗网页也可以被采集,就像采集其他网站一样,但这超出了本章的范围。

  与暗网不同,暗网相对容易采集。 它可以让您采集谷歌爬虫机器人无法获取的深网信息。

  2. 整个网站的网页采集有很多好处:

  (1) 生成网站地图

  使用爬虫采集整个网站,采集所有链接,然后将所有页面组织成网站的实际形式。

  (2) 采集资料

  创建一个专门的垂直搜索平台,并希望采集一些文章(博客、新闻、故事等)。 这些网站虽然很容易采集,但是需要爬虫有足够的深度(我们打算抢数据的网站不多)。 所以创建一个爬虫,递归遍历各个网站,只采集那些网站页面的数据。 一种常用且耗时的网站采集方法是从顶级页面(如首页)开始,然后搜索页面上的所有链接,形成一个列表。 然后再去采集这些链接的每个页面,然后把每个页面找到的链接组成一个新的列表,重复下一轮的采集。

  显然,这是复杂性迅速增长的情况。 如果每个页面有10个链接,网站有5个页面深度(一个中等规模的主流深度),那么如果要采集整个网站,采集的页面总数为10^5,即, 100,000 页。 然而,虽然“5页深,每页10个链接”是网站的主流配置,但实际上,10万页以上的网站很少,因为很大一部分内部链接都是重复的。

  为了避免一个页面被采集两次,链接去重非常重要。 代码运行时,将所有找到的链接放在一起,保存在一个列表中,方便查询(下例参考Python的set类型)。 仅采集新链接,然后从页面中搜索其他链接。

  from urllib.request import urlopen

from bs4 import BeautifulSoup

import re

pages=set()

def getLinks(pageUrl):

global pages

html=urlopen("https://en.wikipedia.org"+pageUrl)

bsObj=BeautifulSoup(html,"html.parser")

<p>

for link in bsObj.findAll("a",href=re.compile("^(/wiki/)")):

if &#39;href&#39; in link.attrs:

if link.attrs["href"] not in pages:

print(newPage)

newPage=link.attrs["href"]

pages.add(newPage)

getLinks(newPage)

getLinks("")</p>

  为了充分展示此网络采集示例的工作原理,我删除了“仅查找内部链接”标准。 爬虫采集的页面范围不再受限制。 只要遇到一个页面,它就会查找所有以/wiki/开头的链接,不管链接是否收录分号。

  一开始用getLinks处理空URL其实就是维基百科的首页,因为空URL在函数里面。 然后遍历首页的每一个链接,查看是否已经在全局变量pages集合中。 如果不是,则打印到屏幕并添加到页面集合,然后使用 getLinks 递归处理链接。 这里要注意一点,python默认的递归限制是1000次,达到递归限制时程序会自动停止。

  3.采集整个网站的数据

  当然,如果网络爬虫只是从一个页面跳到另一个页面,那它是相当乏味的。 为了有效地使用它们,我们需要在抓取时在页面上做一些事情。 让我们看看如何创建一个采集页面标题、正文第一段和编辑页面的链接(如果有)的爬虫。

  与往常一样,决定如何做好这些事情的第一步是查看网站上的几个页面并提出一个采集模式。 通过观察维基百科的几个页面,包括入口页面和非入口页面,比如隐私政策页面,会得到如下规则:

  (1) 所有的标题(在所有页面上,无论是入口页面、编辑历史页面还是其他页面)都在h1-span标签中,页面上只有一个h1标签;

  (2) 如前所述,所有正文都在 div#bodyContent 标签中。 但是,如果我们想更进一步到文本的第一段,使用 div#mw-contet-text-&gt;p 可能会更好(只选择第一段的标签)。这条规则适用于所有页面,除了对于文件页面,不收录部分内容文本(content text)的页面

  (3) 编辑链接只出现在入口页面。 如果有编辑链接,它位于 li#ca-edit-&gt;span-&gt;a。

  完整的程序代码如下:

  from urllib.request import urlopen

from bs4 import BeautifulSoup

import re

<p>

pages=set()

def getLinks(pageUrl):

global pages

html=urlopen("https://en.wikipedia.org"+pageUrl)

bsObj=BeautifulSoup(html,"html.parser")

try:

print(bsObj.h1.get_text())

print(bsObj.find(id="mw-content-text").findAll("p")[0])

print(bsObj.find(id="ca-edit").find("span").find("a").attrs[&#39;href&#39;])

except AttributeError:

print("页面缺少一些属性,Don&#39;t worry")

for link in bsObj.findAll("a",href=re.compile("^(/wiki/)")):

if &#39;href&#39; in link.attrs:

if link.attrs["href"] not in pages:

print("---------\n"+newPage)

newPage=link.attrs["href"]

pages.add(newPage)

getLinks(newPage)

getLinks("")</p>

  由于不可能确保所有类型的数据都出现在每一页上,因此每个打印语句都按从最有可能出现到最不可能出现在页面上的顺序排列。 也就是说,标题标签将出现在每个页面上,因此我们首先尝试获取其数据。 body内容会出现在大部分页面(文件页面除外),所以是第二次抓取的数据。 “编辑”按钮只出现在已经获取到title和body内容的页面,并不是所有的页面都有,所以放在最后。

  汇总:Selenium-网络数据采集工具库-初学篇

  图书馆介绍

  Selenium 是一个强大的网络数据采集工具(),最初是为网站自动化测试而开发的,但它们也可以运行在浏览器上。 Python中的应用函数主要如下:

  项目环境

  操作系统:win10

  蟒蛇版本:3.6

  解析器:pycharm2018

  硒文档:

  使用流程 1.下载安装selenium库

  1.通过PyPI官网站下载()

  2.通过三方管理器pip下载:

  $ pip install selenium

  2.下载第三方浏览器驱动

  Selenium本身没有浏览器,需要配合第三方浏览器使用。

  1、通过PhantomJS(下载地址:)让程序在后台运行,它会将网页加载到内存中,并在页面上执行JavaScript,但不会显示网页的图形界面。 可以处理cookies、JavaScript、headers等。现在Selenium库不支持PhantomJS。

  2.选择在浏览器Chrome/Firefox上运行Selenium:

  需要下载chromedriver.exe()

  版本参考表:

  三、案例(一)Ajax网页测试

  from selenium import webdriver

import time

# 用浏览器运行selenium,需要将下载的chromedriver.exe保存在对应python工程下或指定其他地址

driver = webdriver.Chrome() # chromedriver这里放在工程目录下

# 打开网页

driver.get(&#39;http://pythonscraping.com/pages/javascript/ajaxDemo.html&#39;)

# Ajax测试,由于测试网页有ajax加载2秒,所以这里暂停执行3秒

time.sleep(3)

print(driver.find_element_by_id(&#39;content&#39;).text)

<p>

# 关闭网页

driver.close()</p>

  (2)检测到网页加载成功后执行

  from selenium import webdriver

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

# 创建webdriver

driver = webdriver.Chrome()

# 打开网页

driver.get(&#39;http://pythonscraping.com/pages/javascript/ajaxDemo.html&#39;)

# 检测网页执行。是否出现某个元素后执行

try:

# driver等待10秒,直到网页出现元素标签ID名为loadedButton

elements = WebDriverWait(driver, 10).until(EC.presence_of_element_located(locator=(By.ID, &#39;loadedButton&#39;)))

finally:

# 抓取content元素中的文本

print(driver.find_element_by_id(&#39;content&#39;).text)

# 关闭网页

driver.close()

  阐明:

  一般隐式等待是通过WebDriverWait类和expected_conditions类实现的。 locator 定位器对象用于定位网页元素。 一般定位:ID/CLASS_NAME/CSS_SELECTOR/LINK_TEXT/PARTIAL_LINK_TEXT/NAME/TAG_NAME/XPATH (3)处理重定向

  from selenium import webdriver

import time

from selenium.common.exceptions import StaleElementReferenceException

<p>

def waitForLoad(driver):

elem = driver.find_element_by_tag_name(&#39;html&#39;)

count = 0

while True:

count += 1

if count > 20:

print(&#39;Timing out after 10 seconds and returning&#39;)

return

time.sleep(.5)

try:

elem == driver.find_element_by_tag_name(&#39;html&#39;)

except StaleElementReferenceException as e:

print(e)

return

# 创建webdriver

driver = webdriver.Chrome()

# 打开网页

driver.get(&#39;http://pythonscraping.com/pages/javascript/redirectDemo1.html&#39;)

# 检测网页执行。是否出现某个元素后执行

try:

waitForLoad(driver)

finally:

print(driver.page_source)

# 关闭网页

driver.close()</p>

  注意:*敏*感*词*网页变化的效果可以通过异常类StaleElementReferenceException来实现。 当驱动程序捕获html元素标签失败时,会触发异常,相当于网页的重定向。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线