Python3网络爬虫数据采集(1~3)

一、辅助工具

BeautifulSoup 库 :一款优秀的HTML/XML解析库,采用来做爬虫,不用考虑编码,还有中日韩文的文档,其社区活跃度之高,可见一斑。[注] 这个在解析的时候需要一个解析器,在文档中可以看到,推荐lxml
              
Requests 库:一款比较好用的HTTP库,当然python自带有urllib以及urllib2等库。
           
Fiddler工具:这是一个HTTP抓包软件,能够截获所有的HTTP通讯。

二、知识点

1、流程

发起请求
通过HTTP库向目标站点发起请求,也就是发送一个Request,请求可以包含额外的header等信息,等待服务器响应

获取响应内容
如果服务器能正常响应,会得到一个Response,Response的内容便是所要获取的页面内容,类型可能是HTML,Json字符串,二进制数据(图片或者视频)等类型

解析内容
得到的内容可能是HTML,可以用正则表达式,页面解析库,beautifulsoup进行解析,可能是Json,可以直接转换为Json对象解析,可能是二进制数据,可以做保存或者进一步的处理

保存数据
保存形式多样,可以存为文本,也可以保存到数据库,或者保存特定格式的文件

2、BeautifulSoup的find( )和findAll( )

findAll(tag, attributes, recursive, text, limit, keywords) 
find(tag, attributes, recursive, text, keywords)
  • tag - 查找的标签 (常用)
  • attributes - 查找标签的属性 (常用)
  • recursive - 是否查找全部子标签
  • text - 查找内容为text的标签的数量
  • limit - =1时,findAll()相当于find()
  • keywords - 可以让你选择那些具有指定属性的标签(class因为是关键字,换为class_)

3、BeautifulSoup库对象

  • BeautifulSoup 对象
  • 标签 Tag 对象 :BeautifulSoup 对象通过 find 和 findAll,或者直接调用子标签获取的一列对象或单个对象
  • NavigableString 对象:用来表示标签里的文字,不是标签(有些函数可以操作和生成 NavigableString 对象, 而不是标签对象)。
  • Comment 对象:用来查找 HTML 文档的注释标签,< !-- 像这样 – >

4、正则表达式

在这里插入图片描述

5、获取属性

  • 对于一个标签对象,可以用下面的代码获取它的全部属性
  • myTag.attrs
  • 要注意这行代码返回的是一个 Python 字典对象,可以获取和操作这些属性。比如要获取图 片的资源位置 src
  • myTag.attrs[“src”]

6、链接去重(使用set)

三、获取网络的内外链(有bug未修)

from urllib.request import urlopen
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import re
import datetime
import random

pages = set()
random.seed(datetime.datetime.now())
# 获取页面所有内链的列表
def getInternalLinks(bsObj, includeUrl):
    includeUrl = urlparse(includeUrl).scheme+"://"+urlparse(includeUrl).netloc
    internalLinks = []
    # 找出所有以"/"开头的链接
    for link in bsObj.findAll("a", href=re.compile("^(/|.*"+includeUrl+")")):
        if link.attrs['href'] is not None:
            if link.attrs['href'] not in internalLinks:
                if(link.attrs['href'].startswith("/")):
                    internalLinks.append(includeUrl+link.attrs['href'])
                else:
                    internalLinks.append(link.attrs['href'])
    return internalLinks

# 获取页面所有外链的列表
def getExternalLinks(bsObj, excludeUrl):
    externalLinks = []
    # 找出所有以"http"或"www"开头且不包含当前URL的链接
    for link in bsObj.findAll("a", href=re.compile("^(http|www)((?!"+excludeUrl+").)*$")):
        if link.attrs['href'] is not None:
            if link.attrs['href'] not in externalLinks:
                externalLinks.append(link.attrs['href'])
    return externalLinks

def splitAddress(address):
    addressParts = address.replace("http://", "").split("/")
    return addressParts

# 通过一个链接返回获得外部链接列表中的随机一个
def getRandomExternalLink(startingPage):
    html = urlopen(startingPage)
    bsObj = BeautifulSoup(html, "lxml")
    # urlparse : 将url分为6个部分,返回一个包含6个字符串项目的元组:协议、位置、路径、参数、查询、片段
    # 例如 : https://i.cnblogs.com/EditPosts.aspx?opt=1
    # 分别是 : scheme='https', netloc='i.cnblogs.com', path='/EditPosts.aspx', params='', query='opt=1', fragment=''
    externalLinks = getExternalLinks(bsObj, urlparse(startingPage).netloc)
    if len(externalLinks) == 0:
        print("No external links, looking around the site for one")
        domain = urlparse(startingPage).scheme+"://"+urlparse(startingPage).netloc
        internalLinks = getInternalLinks(bsObj, domain)
        return getRandomExternalLink(internalLinks[random.randint(0, len(internalLinks)-1)])
    else:
        return externalLinks[random.randint(0, len(externalLinks)-1)]

# 递归输出每一个外链
def followExternalOnly(startingSite):
    externalLink = getRandomExternalLink(startingSite)
    print("Random external link is: "+externalLink)
    followExternalOnly(externalLink)

followExternalOnly("http://www.csdn.net")

猜你喜欢

转载自blog.csdn.net/weixin_44485744/article/details/109239259