采集网站内容(互联网上搜索引擎可以抓到的那部分网络都是深网)

优采云 发布时间: 2022-03-21 21:23

  采集网站内容(互联网上搜索引擎可以抓到的那部分网络都是深网)

  前言:

  网络爬虫被称为网络爬虫,因为它们沿着网络爬行。它们的本质是一种递归方式。为了找到一个URL链接,他们必须先获取网页的内容,检查页面的内容,寻找另一个URL,然后获取该URL对应的网页内容,重复上述过程。

  1 遍历单个域名

  示例:编写一段 Python 代码,获取 Wikipedia 网站 的任意页面并提取该页面的链接

  1from urllib.request import urlopen

2from bs4 import BeautifulSoup

3

4html = urlopen("http://en.wikipedia.org/wiki/Kevin_Bacon")

5bsObj = BeautifulSoup(html)

6for link in bsObj.findAll("a"):

7 if 'href' in link.attrs:

8 print(link.attrs['href'])

9

  观察生成的链接列表,你会发现“入口链接”和“其他链接”的区别,你会发现“入口链接”有三个共同点:

  我们可以使用这些规则稍微调整代码以获得术语链接:

  1for link in bsObj.find("div", {"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$")):

2 if 'href' in link.attrs:

3 print(link.attrs['href'])

4

  为了改进它,该实现在 网站 上实现了从一个链接到另一个链接的随机跳转:

  1from urllib.request import urlopen

2from bs4 import BeautifulSoup

3import datetime

4import random

5import re

6

7random.seed(datetime.datetime.now())

8def getLinks(articleUrl):

9 html = urlopen("http://en.wikipedia.org"+articleUrl)

10 bsObj = BeautifulSoup(html)

11 return bsObj.find("div", {"id":"bodyContent"}).findAll("a",href=re.compile("^(/wiki/)((?!:).)*$"))

12

13links = getLinks("/wiki/Kevin_Bacon")

14while len(links) > 0:

15 newArticle = links[random.randint(0, len(links)-1)].attrs["href"]

16 print(newArticle)

17 links = getLinks(newArticle)

18

  2 采集整个网站

  [$]补充:网站有深网、暗网、浅网。与表面网相反,深层网是网的一部分。浅网是可以抓取的互联网搜索引擎

  到网络的那个部分。据不完全统计,大约90%的互联网实际上是深网。暗网,也称为暗网或暗网,完全是另一个“怪物”。它们也建立在现有网络之上,但使用 Tor 客户端和运行在 HTTP 之上的新协议,为信息交换提供安全隧道。

  网站采集的一个常见且耗时的方法是从一个顶级页面(例如首页)开始,然后搜索页面上的所有链接,形成一个列表。再次转到 采集 这些链接中的每一个,然后形成每个页面上找到的链接的新列表,重复下一轮 采集。

  [*]注意:为了避免一个页面被采集两次,链接去重非常重要。

  1from urllib.request import urlopen

2from bs4 import BeautifulSoup

3import re

4

5pages = set()

6def getLinks(pageUrl):

7 global pages

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

9 bsObj = BeautifulSoup(html)

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

11 if 'href' in link.attrs:

12 if link.attrs['href'] not in pages:

13 # 我们遇到了新页面

14 newPage = link.attrs['href']

15 print(newPage)

16 pages.add(newPage)

17 getLinks(newPage)

18getLinks("")

19

  [*] 注意:如果递归运行次数过多,之前的递归程序很可能会崩溃。

  Python 的默认递归限制(程序递归调用自身的次数)是 1000 次。

  为了有效地使用它们,我们在使用爬虫时需要在页面上做几件事:

  1from urllib.request import urlopen

2from bs4 import BeautifulSoup

3import re

4

5pages = set()

6def getLinks(pageUrl):

7 global pages

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

9 bsObj = BeautifulSoup(html)

10 try:

11 print(bsObj.h1.get_text())

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

13 print(bsObj.find(id="ca-edit").find("span").find("a").attrs['href'])

14 except AttributeError:

15 print("页面缺少一些属性!不过不用担心!")

16

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

18 ...#与上面一样

19

  3 通过互联网采集

  在编写爬虫以随意跟踪外部链接之前,请先问自己几个问题:

  几个灵活的 Python 函数可以组合起来实现不同类型的网络爬虫,只需不超过 50 行代码即可轻松编写:

  1from urllib.request import urlopen

2from bs4 import BeautifulSoup

3import re

4import datetime

5import random

6

7pages = set()

8random.seed(datetime.datetime.now())

9# 获取页面所有内链的列表

10def getInternalLinks(bsObj, includeUrl):

11 internalLinks = []

12 # 找出所有以"/"开头的链接

13 for link in bsObj.findAll("a", href=re.compile("^(/|.*"+includeUrl+")")):

14 if link.attrs['href'] is not None:

15 if link.attrs['href'] not in internalLinks:

16 internalLinks.append(link.attrs['href'])

17 return internalLinks

18

19# 获取页面所有外链的列表

20def getExternalLinks(bsObj, excludeUrl):

21 externalLinks = []

22 # 找出所有以"http"或"www"开头且不包含当前URL的链接

23 for link in bsObj.findAll("a",href=re.compile("^(http|www)((?!"+excludeUrl+").)*$")):

24 if link.attrs['href'] is not None:

25 if link.attrs['href'] not in externalLinks:

26 externalLinks.append(link.attrs['href'])

27 return externalLinks

28

29def splitAddress(address):

30 addressParts = address.replace("http://", "").split("/")

31 return addressParts

32

33def getRandomExternalLink(startingPage):

34 html = urlopen(startingPage)

35 bsObj = BeautifulSoup(html)

36 externalLinks = getExternalLinks(bsObj, splitAddress(startingPage)[0])

37 if len(externalLinks) == 0:

38 internalLinks = getInternalLinks(startingPage)

39 return getNextExternalLink(internalLinks[random.randint(0,len(internalLinks)-1)])

40 else:

41 return externalLinks[random.randint(0, len(externalLinks)-1)]

42

43def followExternalOnly(startingSite):

44 externalLink = getRandomExternalLink("http://oreilly.com")

45 print("随机外链是:"+externalLink)

46 followExternalOnly(externalLink)

47

48followExternalOnly("http://oreilly.com")

49

  网站无法保证在主页上始终可以找到外部链接。这时候为了能够找到外部链接,就需要一个类似于前面案例中使用的采集方法的方法,即递归深入到一个网站,直到找到外部链接找到了,然后停止。

  如果我们的目标是采集一个网站所有反向链接,并记录每个反向链接,我们可以添加以下函数:

  1# 收集网站上发现的所有外链列表

2allExtLinks = set()

3allIntLinks = set()

4def getAllExternalLinks(siteUrl):

5 html = urlopen(siteUrl)

6 bsObj = BeautifulSoup(html)

7 internalLinks = getInternalLinks(bsObj,splitAddress(siteUrl)[0])

8 externalLinks = getExternalLinks(bsObj,splitAddress(siteUrl)[0])

9 for link in externalLinks:

10 if link not in allExtLinks:

11 allExtLinks.add(link)

12 print(link)

13 for link in internalLinks:

14 if link not in allIntLinks:

15 print("即将获取链接的URL是:"+link)

16 allIntLinks.add(link)

17 getAllExternalLinks(link)

18getAllExternalLinks("http://oreilly.com")

19

  [*]注意:服务器端重定向,你通常不用担心。如果您使用的是 Python 3.x 版本的 urllib 库,它会自动处理重定向。

  4 使用 Scrapy采集

  尽管编写 Scrapy 爬虫很简单,但完成爬虫需要一些设置。要在当前目录中创建一个新的 Scrapy 项目,请执行以下代码:

  $scrapy startproject wikiSpider(wikiSpider 是新项目的名称。)

  1文件夹的目录结构如下所示:

2• scrapy.cfg

3 — wikiSpider

4 — __init.py__

5 — items.py

6 — pipelines.py

7 — settings.py

8 — spiders

9 — __init.py__

10

  要创建蜘蛛,我们需要将 articleSpider.py 文件添加到 wikiSpider/wikiSpider/spiders/ 文件夹中。另外,在 items.py 文件中,我们需要定义一个 Article 类。items.py 文件应如下所示:

  1# -*- coding: utf-8 -*-

2# Define here the models for your scraped items

3#

4# See documentation in:

5# http://doc.scrapy.org/en/latest/topics/items.html

6from scrapy import Item, Field

7class Article(Item):

8 # define the fields for your item here like:

9 # name = scrapy.Field()

10 title = Field()

11

  Scrapy 中的每个 Item 对象代表 网站 上的一个页面。

  在新创建的articleSpider.py文件中,编写如下代码:

  1from scrapy.selector import Selector

2from scrapy import Spider

3from wikiSpider.items import Article

4

5class ArticleSpider(Spider):

6 name="article"

7 allowed_domains = ["en.wikipedia.org"]

8 start_urls = ["http://en.wikipedia.org/wiki/Main_Page","http://en.wikipedia.org/wiki/Python_%28programming_language%29"]

9

10 def parse(self, response):

11 item = Article()

12 title = response.xpath('//h1/text()')[0].extract()

13 print("Title is: "+title)

14 item['title'] = title

15 return item

16

  在主 wikiSpider 目录中使用以下命令运行 ArticleSpider: $ scrapy crawl article

  此行将使用文章名称 article 调用爬虫。

  [$] 添加:

  日志显示级别可以在Scrapy项目的setting.py文件中设置:

  LOG_LEVEL = '错误'

  Scrapy 日志有五个级别,按范围升序排列如下:

  • 危急

  • 错误

  • 警告

  • 调试

  • 信息

  如果日志级别设置为 ERROR,则只会显示 CRITICAL 和 ERROR 日志。

  如果日志级别设置为 INFO,则将显示所有信息,否则相同。

  日志不仅可以在终端显示,还可以输出到单独的文件中,使用如下命令:

  $scrapy 爬取文章 -s LOG_FILE=wiki.log

  Scrapy 支持将这些信息保存为不同的输出格式,例如 CSV、JSON 或 XML 文件格式,对应的命令如下:

  $scrapy 抓取文章 -o article.csv -t csv

  $scrapy 抓取文章 -oarticles.json -t json

  $scrapy 抓取文章 -o article.xml -t xml

  Scrapy 是处理与网络数据相关的问题的绝佳工具采集。它会自动采集所有 URL 并将它们与指定规则进行比较;确保所有 URL 都是唯一的;根据需要规范化相关 URL;并递归搜索更深的页面。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线