经过前两天的折腾也大概对数据采集慢慢形成概念,在表面来看人工肉眼能够检索到的数据是非常有限的,即浅网(Surface Web),这一部分只占到互联网资源的百分之十左右,也就是搜索引擎能够抓取到的地方,至于真正的数据到底有多少,无法估量。但值得庆幸的是基于http协议的网页虽然有些部分搜索引擎抓取不到,但是爬虫可以。有了前面的一些折腾,来电新鲜的:
在采取数据之前至少得明确目标,依旧是那个熟悉的百度:

from urllib import urlopen
from bs4 import BeautifulSoup
import re
import datetime
import random
pages = set()
random.seed(datetime.datetime.now())
def getInternalLinks(bsObj, includeUrl):
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:
internalLinks.append(link.attrs['href'])
return internalLinks
def getExternalLinks(bsObj, excludeUrl):
externalLinks = []
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,"html.parser")
externalLinks = getExternalLinks(bsObj, splitAddress(startingPage)[0])
if len(externalLinks) == 0:
internalLinks = getInternalLinks(startingPage)
return getNextExternalLink(internalLinks[random.randint(0,len(internalLinks)-1)])
else:
return externalLinks[random.randint(0, len(externalLinks)-1)]
def followExternalOnly(startingSite):
externalLink = getRandomExternalLink("https://baidu.com")
print("Random Page is:"+externalLink)
followExternalOnly(externalLink)
followExternalOnly("https://baidu.com")
上面的程序从https://baidu.com开始,随机的从一个外链跳转的另一个外链。

可以看到百度周边的一些网页,文库 学术什么的。
也可以添加一些新的部分:手机网站上发现的所有外链列表:
allExtLinks = set()
allIntLinks = set()
def getAllExternalLinks(siteUrl):
html = urlopen(siteUrl)
bsObj = BeautifulSoup(html)
internalLinks = getInternalLinks(bsObj, splitAddress(siteUrl)[0])
externalLinks = getExternalLinks(bsObj, splitAddress(siteUrl)[0])
for link in externalLinks:
if link not in allExtLinks:
allExtLinks.add(link)
print(link)
for link in internalLinks:
if link not in allIntLinks:
print("will get:" + link)
allIntLinks.add(link)
getAllExternalLinks(link)
getAllExternalLinks("https://baidu.com")
这样程序流程如下:
这里遇到一个问题:如何解决301重定向问题?(是当用户或搜索引擎向网站服务器发出浏览请求时,服务器返回的HTTP数据流中头信息(header)中的状态码的一种,表示本网页永久性转移到另一个地址。)
重定向( redirect)允许一个网页在不同的域名下显示。重定向有两种形式:
• 服务器端重定向,网页在加载之前先改变了 URL;
• 客户端重定向,有时你会在网页上看到“ 10 秒钟后页面自动跳转到……”之类的消息,表示在跳转到新 URL 之前网页需要加载内容。
服务器端重定向,通常不用担心。如果用 Python 3.x 版本的 urllib 库,它会自动处理重定向。不过要注意,有时候要采集的页面的 URL 可能并不是当前所在页面的 URL。
尝试使用Scrapy采集
在实际的使用当中往往我们都在重复一件相同的事情:找出页面的所有的链接,跳转至新的页面,然后狗住继续执行这样的一个操作。这里可以使用Scrapy来帮助你大幅度降低网页链接查找和识别。这个Python库可以说是我py2.7的 福音23333.
安装Scrapy:pip install Scrapy(如果报错超时就pip --default-timeout=100 install -U pip后再次尝试,还不行的话https://pypi.python.org/simple/scrapy/手动滑稽吧)
安装完成之后我们得先创建工作环境:
使用cmd 执行命令:scrapy startproject src 其中src是你想创建的工作路径。在哪里执行就会在 哪里创建。
然后将项目导入pychrom


接下来继续:在spiders中添加一个新的.py,并修改items.py:
from scrapy.selector import Selector
from scrapy import Spider
from scr.items import Article
class ArticleSpider(Spider):
name="article"
allowed_domains = ["baike.baidu.com"]
start_urls = ["https://baike.baidu.com/item/Avicii",
"https://baike.baidu.com/item/Python_%28programming_language%29"]
def parse(self, response):
item = Article()
title = response.xpath('//h1/text()')[0].extract()
print("Title is: "+title)
item['title'] = title
return item
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html
from scrapy import Item, Field
class Article(Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = Field()
然后添加begin.py作为启动:
from scrapy import cmdline
cmdline.execute("scrapy crawl article".split())
最终目录为:

开始配置信息:


此刻便可以进行运行:(若此时py的import库出现问题请自行重装:0.0因为我就是出异常了哎)
贴上来先暂存,哪天改正填平这个坑了就改掉QAQ:
Traceback (most recent call last):
File "D:\Python\lib\site-packages\twisted\internet\defer.py", line 1386, in _inlineCallbacks
result = g.send(result)
File "D:\Python\lib\site-packages\scrapy\crawler.py", line 95, in crawl
six.reraise(*exc_info)
File "D:\Python\lib\site-packages\scrapy\crawler.py", line 77, in crawl
self.engine = self._create_engine()
File "D:\Python\lib\site-packages\scrapy\crawler.py", line 102, in _create_engine
return ExecutionEngine(self, lambda _: self.stop())
File "D:\Python\lib\site-packages\scrapy\core\engine.py", line 69, in __init__
self.downloader = downloader_cls(crawler)
File "D:\Python\lib\site-packages\scrapy\core\downloader\__init__.py", line 88, in __init__
self.middleware = DownloaderMiddlewareManager.from_crawler(crawler)
File "D:\Python\lib\site-packages\scrapy\middleware.py", line 58, in from_crawler
return cls.from_settings(crawler.settings, crawler)
File "D:\Python\lib\site-packages\scrapy\middleware.py", line 34, in from_settings
mwcls = load_object(clspath)
File "D:\Python\lib\site-packages\scrapy\utils\misc.py", line 44, in load_object
mod = import_module(module)
File "D:\Python\lib\importlib\__init__.py", line 37, in import_module
__import__(name)
File "D:\Python\lib\site-packages\scrapy\downloadermiddlewares\retry.py", line 20, in <module>
from twisted.web.client import ResponseFailed
File "D:\Python\lib\site-packages\twisted\web\client.py", line 42, in <module>
from twisted.internet.endpoints import HostnameEndpoint, wrapClientTLS
File "D:\Python\lib\site-packages\twisted\internet\endpoints.py", line 41, in <module>
from twisted.internet.stdio import StandardIO, PipeAddress
File "D:\Python\lib\site-packages\twisted\internet\stdio.py", line 30, in <module>
from twisted.internet import _win32stdio
File "D:\Python\lib\site-packages\twisted\internet\_win32stdio.py", line 9, in <module>
import win32api
ImportError: No module named win32api
这个吃我缩进=-=MD
还有这个正则表达式网上生产的和python解读好像不太一样。。。我拿自己的站点测试会出现一些奇怪的问题。。容我缓缓 😕
历害了弢老铁