动态线条
动态线条end

Python爬虫

爬虫

网络爬虫(又被称为网页蜘蛛,网络机器人),就是模拟浏览器发送网络请求,接收请求响应,一种按照一定的规则,自动地榨取互联网信息的程序。原则上,只要浏览器(客户端)能做的事情,爬虫都能做。

爬虫不是python独有的,可以做爬虫的语言有很多例如:PHP,JAVA,C#,C++,Python,选择Python是因为Python相对来说比较简单、功能也比较齐全。

首先,大体流程分为三步:
1、爬取网页(获取网页信息)
2、逐一解析数据(获得需要的数据)
3、保存数据

爬取网页

可能需要用到的函数库
urllib、reqest、fake_useragent

这里也分为三步 1、创建请求对象 2、发送网络请求 3、接收响应对象

创建请求对象,如果我们直接向某个url发起请求,会被对方识别出来是爬虫,往往会被限制而得不到响应。所以需要进行伪装,创建一个包含信息的请求头逃避对方识别。

import urllib.request
from fake_userAgent import userAgent
import requests


# 指定UA
headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:65.0) Gecko/20100101 Firefox/65.0'}

# 随机UA
ua = USerAgent();
headers = {'User-Agent':ua}

# 发送请求 (两种方式)

req = urllib.request.Request(url,headers)
req = requests.get(url.,hreaders)

# 获得响应
```python
html = req.read().decode('utf-8')

解析网页数据

响应后会获得整个网页代码后,我们需要进行解析,只保留我们需要的元素。解析一般有以下方式。1、正则表达式阶解析 2、BeautifulSoup解析 3、lxml的XPath解析 4、requests-html解析

# 正则表达式
findLink = re.compile(r'<a href="(.*?)">')  
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S)
findTitle = re.compile(r'<span class="title">(.*)</span>')
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')

# BeautifulSoup
soup = BeautifulSoup(req.text, 'lxml') # 使用lxml解析页面代码 r.test为获取页面代码
info_list = soup.find_all(attrs={'class': 'ptlist ptlist-pc'}) # 两次定位 先找到整个信息区域
tit_list = info_list[0].find_all(attrs={'class': 'tit'}) # 在此区域内获取游戏名 find_all返回的是list

#lxml

# requests-html

保存网页

获得到需要的数据后,我们一般将数据进行存储。一般采用几种方式。1、表格(文本)文件 2、数据库 3、HTML网页

# Excel文件
 book = xlwt.Workbook(encoding="utf-8",style_compression=0) #创建workbook对象
    sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True) #创建工作表
    col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息")
    for i in range(0,8):
        sheet.write(0,i,col[i])  #列名
    for i in range(0,250):
        # print("第%d条" %(i+1))       #输出语句,用来测试
        data = datalist[i]
        for j in range(0,8):
            sheet.write(i+1,j,data[j])  #数据
    book.save(savepath) #保存

# 数据库
 L = []
        sql = 'insert into filmtab values(%s,%s,%s)'
        # 整理数据
        for r in r_list:
            t = (
                r[0].strip(),
                r[1].strip()[3:],
                r[2].strip()[5:15]
            )
            L.append(t)
            print(L)
        # 一次性插入多条数据 L:[(),(),()]
        try:
            self.cursor.executemany(sql, L)
            # 将数据提交到数据库
            self.db.commit()
        except:
            # 发生错误就回滚
            self.db.rollback()
      
 # HTML网页
  with open(filename, 'w', encoding='utf-8') as f:
            f.write(html)

爬虫大致流程就是这样,关键就是如何解析网页获取关键数据信息。
这里提供两个完整代码供参考。

抓取猫眼T100保存csv文件(对方增加了滑块验证,运行前需要先打开猫眼网站进行验证)

"""
    在开始编程之前,首先要确定页面类型(静态页面或动态页面),
    其次要找出页面url规律,
    最后通过分析页面元素结构来确定正则表达式,从而提取页面信息
"""
import random
import time
import requests
import re
from fake_useragent import UserAgent
import csv
# 点击右键查看页面源码,确定要抓取的信息是否存在页面内,确认是静态页面

# 确认url规律,多浏览几个页面,才可以总结出url规律
"""
    第一页:https://www.maoyan.com/board/4?offset=0
    第二页:https://www.maoyan.com/board/4?offset=10
    ……
    第N页:https://www.maoyan.com/board/4?offset=(n-1)*10
"""
# 通过分析页面元素结构确定正则表达式
"""
<div class="movie-item-info">
        <p class="name"><a href="/films/1200486" title="我不是药神" data-act="boarditem-click" data-val="{movieId:1200486}">我不是药神</a></p>
        <p class="star">
                主演:徐峥,周一围,王传君
        </p>
<p class="releasetime">上映时间:2018-07-05</p>    </div>
正则表达式
<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>
"""



class MaoyanSpider(object):

    # 自定义初始化页面
    def __init__(self):
        self.url = 'http://www.maoyan.com/board/4?offset={}'

    # 请求函数
    def get_html(self, url):
        ua = UserAgent()
        headers = {'User-Agent': ua.edge,
                   'Cookie': '__mta=208959789.1585106920033.1593509077842.1593509107607.47; _'
                             'lxsdk_cuid=1710fbc224bc8-0048503dcb84eb-f313f6d-1a298c-1710fbc22'
                             '4cc8; mojo-uuid=bc73035186bc203e1e0a1a9d69cf0c8f; uuid_n_v=v1; u'
                             'uid=010A4750BAB111EA977B252D9527D646FCA82B59C6B54FB3934C361D7196'
                             '43F2; _csrf=ab7e60b187089a5c797755f042abdbd14eed1760f8308dc45557'
                             '0ee9ea4edfa2; mojo-session-'}
        r = requests.post(url=url, headers=headers)
        self.parse_html(r.text)

    # 解析函数
    def parse_html(self, html):
        re_bds = ('<div class="movie-item-info">.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?c'
                  'lass="releasetime">(.*?)</p>')
        pattern = re.compile(re_bds, re.S)
        r_list = pattern.findall(html)
        self.sava_html(r_list)

    def sava_html(self, r_list):
        with open('maoyan.csv', 'a', newline='') as csvfile:
            writer = csv.writer(csvfile)
            for r in r_list:
                name = r[0].strip()
                star = r[1].strip()[3:]
                time = r[2].strip()[5:15]
                L = [name, star, time]
                writer.writerow(L)
                print(name, star, time)

    def run(self):
        for offset in range(0, 90, 10):
            url = self.url.format(offset)
            self.get_html(url)
            time.sleep(random.uniform(1, 2))


if __name__ == '__main__':
    try:
        spider = MaoyanSpider()
        spider.run()
    except Exception as e:
        print('错误:', e)


抓取猫眼T100保存到数据库

# coding=gbk
import random
import time

import pymysql
import requests
import re
from fake_useragent import UserAgent
import csv


class MaoyanSpider(object):

    # 自定义初始化页面
    def __init__(self):
        self.url = 'http://www.maoyan.com/board/4?offset={}'
        # 数据库连接
        self.db = pymysql.Connect(
            host='主机号', user='用户名', password='密码', database='数据库名')
        # 创建游标对象
        self.cursor = self.db.cursor()

    # 请求函数
    def get_html(self, url):
        ua = UserAgent()
        headers = {'User-Agent': ua.edge,
                   'Cookie': '__mta=208959789.1585106920033.1593509077842.1593509107607.47; _'
                             'lxsdk_cuid=1710fbc224bc8-0048503dcb84eb-f313f6d-1a298c-1710fbc22'
                             '4cc8; mojo-uuid=bc73035186bc203e1e0a1a9d69cf0c8f; uuid_n_v=v1; u'
                             'uid=010A4750BAB111EA977B252D9527D646FCA82B59C6B54FB3934C361D7196'
                             '43F2; _csrf=ab7e60b187089a5c797755f042abdbd14eed1760f8308dc45557'
                             '0ee9ea4edfa2; mojo-session-'}
        r = requests.post(url=url, headers=headers)
        self.parse_html(r.text)

    # 解析函数
    def parse_html(self, html):
        re_bds = ('<div class="movie-item-info">.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?c'
                  'lass="releasetime">(.*?)</p>')
        pattern = re.compile(re_bds, re.S)
        r_list = pattern.findall(html)
        self.sava_html(r_list)

    def sava_html(self, r_list):
        L = []
        sql = 'insert into filmtab values(%s,%s,%s)'
        # 整理数据
        for r in r_list:
            t = (
                r[0].strip(),
                r[1].strip()[3:],
                r[2].strip()[5:15]
            )
            L.append(t)
            print(L)
        # 一次性插入多条数据 L:[(),(),()]
        try:
            self.cursor.executemany(sql, L)
            # 将数据提交到数据库
            self.db.commit()
        except:
            # 发生错误就回滚
            self.db.rollback()

    def run(self):
        for offset in range(0, 100, 10):
            url = self.url.format(offset)
            self.get_html(url)
            time.sleep(random.uniform(1, 3))

        # 断开游标与数据库连接
        self.cursor.close()
        self.db.close()


if __name__ == '__main__':
    try:
        start = time.time()
        spider = MaoyanSpider()
        spider.run()
        end = time.time()
        print('执行时间%.2f' % (end - start))

    except Exception as e:
        print('错误:', e)

    评论
    0 评论
avatar

取消