Python 网络爬虫 学习笔记.CH3 采集数据

96
硼酸滴耳液
2017.09.24 15:46* 字数 713

教材:《Web Scraping with Python——Collecting Data from the Modern Web》© 2015 by Ryan Mitchell


之所以叫网络爬虫(Web crawler),是因为它们可以沿着网络爬行。本质就是一种递归方式。为了找到 URL 链接,爬虫必须首先获取网页内容,检查这个页面的内容,再寻找另一个 URL,然后获取 URL 对应的网页内容,不断循环这一过程。

提取页面链接:

from urllib.request import urlopen

from bs4 import BeautifulSoup


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

bsObj = BeautifulSoup(html)

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

    if 'href' in link.attrs:

    print(link.attrs['href'])

过滤多余的连接:

以仅提取“词条链接”为例,相比于“其他链接”,“词条链接”:

• 都在 id 是 bodyContent 的 div 标签里 

• URL 链接不包含分号

• URL 链接都以 /wiki/ 开头

——利用find()方法和正则表达式过滤“其他链接”:

from urllib.request import urlopen

from bs4 import BeautifulSoup

import datetime

import random

import re


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

def getLinks(articleUrl):

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

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

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

links = getLinks("/wiki/Kevin_Bacon")

while len(links) > 0:

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

    print(newArticle)

links = getLinks(newArticle)

链接去重:

为了避免一个页面被采集两次,链接去重是非常重要的。在代码运行时,把已发现的所有链接都放到一起,并保存在方便查询的列表里(下文示例指 Python 的集合 set 类型)。只有“新”链接才会被采集,之后再从页面中搜索其他链接:

遍历首页上每个链接,并检查是否已经在全局变量集合 pages 里面了(已经采集的页面集合)。如果不在,就打印到屏幕上,并把链接加入pages 集合,再用 getLinks 递归地处理这个链接。

from urllib.request import urlopen

from bs4 import BeautifulSoup

import re


pages = set()

def getLinks(pageUrl):

global pages

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

bsObj = BeautifulSoup(html)

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

if 'href' in link.attrs:

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

# we meet the new page

newPage = link.attrs['href']

print(newPage)

pages.add(newPage)

getLinks(newPage)

getLinks("")

收集整个网站数据的组合程序:

from urllib.request import urlopen

from bs4 import BeautifulSoup

import re

pages = set()

def getLinks(pageUrl):

global pages

html = urlopen("http://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['href'])

except AttributeError:

print("This page is missing something! No worries though!")

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

if 'href' in link.attrs:

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

#We have encountered a new page

newPage = link.attrs['href']

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

pages.add(newPage)

getLinks(newPage)

getLinks("")

日记本