Python3 scrapy error: Microsoft Visual C++ 14.0 is required

安装方法

首先安装wheel

pip install wheel

安装完成后验证是否成功

wheel

然后去 http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml 网站下载Twisted,
进到网站=>搜索’Twisted’=>挑选合适版本下载

把下载的.whl文件放在一个容易寻找的地址(我放在了D:\)
然后在控制台进入该地址
在该地址下输入

pip install [whl]

注:[whl]表示你的.whl文件,一定要全名,XXXX.whl

因为Scrapy框架基于Twisted

所以,要做的就是去网站下载Twisted之类的安装文件,先把它们装上。

最后装Scrapy

同样去 http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml 网站下载Scrapy,
进到网站=>搜索’Scrapy’=>下载
和上面一样安装

pip install [whl]

OK,现在好啦!

建个项目测试一下

scrapy startproject pyjy

注:pyjy为项目名

python 爬虫去重方法

  • 将访问过的url保存到数据库中
  • 将访问过的url保存到set中,只需要o(1)的代价就可以查询url 占用内存估计100000000*2byte*50个字符/1024/1024/1024=9G
  • 经过md5等方法哈希后保存到set中
  • 用bitmap方法,将访问过的url通过hash函数映射到某一位
  • bloomfilter方法对bitmap进行改进,多重hash函数降低冲突

 

深度优先和广度优先原理

深度优先输出A、B、D、E、I、C、F、G、H (递归实现)

def depth_tree(tree_node):
    if tree_node is not None:
        print(tree_node._data)
        if tree_node._left is not None:
            return depth_tree(tree_node._left)
        if tree_node.right is not None:
            return depth_tree(tree_node._right)

广度优先输出A、B、C、D、E、F、G、H、I (队列实现)

def lelve_queue(root):
    """利用队列实现树的广度优先遍历"""
    if root is None:
        return
    my_queue = {}
    node = root
    my_queue.append(node)
    while my_queue:
        node = my_queue.pop(0)
        print(node.elem)
        if node.lchild is not None:
            my_queue.append(node.lchild)
        if node.rchild is not None:
            my_queue.append(node.rchild)

pytho3 存储数据到MySql

安装pymysql

通过pip安装pymysql

pip install pymysql

通过安装文件

python setup.py install

存储数据到mysql

引入开发包

import pymysql.cursors

获取数据库链接

connection = pymysql.connect(

host = 'localhost',

user = 'root',

password = ''123456,

db = 'wikiurl',

charset = 'utf8mb4'

)

获取会话指针

connection.cursor()

执行sql语句

cursor.execute(sql, (参数1, 参数n))

提交

connection.commit()

关闭

connection.close()

例子:

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

# 引入开发包
from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import pymysql

# 请求url并把结果用utf-8编码
resp = urlopen("https://zh.wikipedia.org/wiki/%E9%A6%96%E9%A1%B5").read().decode("utf-8")

# 使用BeautifulSoup去解析
soup = BeautifulSoup(resp, "html.parser")

# 获取所有以/wiki/开头的a标签的href属性
listUrl = soup.findAll("a", href=re.compile("^/wiki/"))

# 输出所有的词条对应的名称和url
for url in listUrl:

    # 过滤以.jpg|JPG结尾的url
    if not re.search(r".jpg|.JPG$", url["href"]):

        # 输出url的文字和对应的链接
        print(url.get_text(), "<---->", "https://zh.wikipedia.org" + url["href"])

        # 获取数据库链接
        connection = pymysql.connect(
            host="127.0.0.1",
            user="root",
            password="",
            db="wikiurl",
            charset="utf8mb4"
        )

        try:
            # 获取会话指针
            with connection.cursor() as cursor:
                # 创建sql语句
                sql = "insert into `urls` (`urlname`, `urlhref`) VALUES (%s, %s)"
                cursor.execute(sql, (url.get_text(), "https://zh.wikipedia.org" + url["href"]))
                connection.commit()
        finally:
            connection.close()

读取mysql数据

得到总记录数

cursor.execute()

查询下一行

cursor.fetchone()

得到指定大小

cursor.ftechmany(size=None)

例子

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

# 引入开发包
import pymysql.cursors

# 获取数据库链接
connection = pymysql.connect(
    host="127.0.0.1",
    user="root",
    password="",
    db="wikiurl",
    charset="utf8mb4"
)

try:
    # 获取会话指针
    with connection.cursor() as cursor:
        # 创建sql语句
        sql = "select * from `urls` where `urlname` is not NULL"
        count = cursor.execute(sql)
        print(count)
        result = cursor.fetchmany(3)
        # result = cursor.fetchall()
        print(result)
finally:
    connection.close()

Python3 BeautifulSoup

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

# 引入开发包
from urllib.request import urlopen
from bs4 import BeautifulSoup
import re

# 请求url并把结果用utf-8编码
resp = urlopen("https://zh.wikipedia.org/wiki/%E9%A6%96%E9%A1%B5").read().decode("utf-8")

# 使用BeautifulSoup去解析
soup = BeautifulSoup(resp, "html.parser")

# 获取所有以/wiki/开头的a标签的href属性
listUrl = soup.findAll("a", href=re.compile("^/wiki/"))

# 输出所有的词条对应的名称和url
for url in listUrl:
    
    # 过滤以.jpg|JPG结尾的url
    if not re.search(r".jpg|.JPG$", url["href"]):
        
        # 输出url的文字和对应的链接
        print(url.get_text(), "<---->", "https://zh.wikipedia.org" + url["href"])

Python3 urllib

使用步骤

导入urlib库的request模块

from urllib import request

请求Url

resp = request.urlopen('http://www.baidu.com')

使用响应对象输出数据

print(resp.read().decode("utf-8"))

模拟真实浏览器

携带User-Agent头

req = request.Request(url)

req.add_header(key, value)

resp = request.urlopen(req)

print(resp.read().decode("utf-8"))

例子

from urllib import request

req = request.Request('http://www.baidu.com')
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36')
reqs = request.urlopen(req)
print(reqs.read().decode('utf-8'))

使用Post

导入urllib库下面的parse

from urllib import parse

使用urlencode生成post数据

postData = parse.urlencode([

(key1, val1)

(key2, val2)

(keyn, valn)

])

使用postData发送post请求

request.urlopen(req, data=postData.encode('utf-8'))

得到请求状态

resp.status

得到服务器的类型

resp.reason

例子

from urllib import request
from urllib import parse

postData = parse.urlencode([
    ("name", "xiaoming"),
    ("age", "20"),
    ("area", "sichuan"),
])

req = request.urlopen('http://www.baidu.com', data=postData.encode("utf-8"))
print(req.read().decode("utf-8"))

python中 __call__

在Python中,函数其实是一个对象:

>>> f = abs
>>> f.__name__
'abs'
>>> f(-123)
123

由于 f 可以被调用,所以,f 被称为可调用对象。

所有的函数都是可调用对象。

一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()

我们把 Person 类变成一个可调用对象:

class Person(object):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

    def __call__(self, friend):
        print 'My name is %s...' % self.name
        print 'My friend is %s...' % friend

现在可以对 Person 实例直接调用:

>>> p = Person('Bob', 'male')
>>> p('Tim')
My name is Bob...
My friend is Tim...

单看 p(‘Tim’) 你无法确定 p 是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著。