商业爬虫

Day1

  图书推荐

    图解HTTP,日本人写的  

  爬虫用处

    诸葛

    工商大数据

  分类

    通用爬虫  

    聚焦爬虫

  https://www.jd.com/robots.txt

Day2

  User-Agent池

  Ip代理池

Day4

  一个用户在不同的地方,不同的浏览器不停的登录,很有可能被封。面试遇到过。

  解决方法:多个账号。多个IP统一并发

Day5

  proxies

  ssl

import requests


headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0',
}

#1 代理IP 字典形式
#2 SSL认证
#HTTPS,是有第三方CA证书认证,但是12306 ,虽然是http是,但他不是CA证书,他是自己颁发的证书,解决方法是
#告诉web忽略证书访问,用到的参数是verify
#3 GET请求 传参 query POST请求传参 formdata
free_proxy = {'HTTP':'222.189.246.94:9999'}
login_url = 'https://www.12306.cn/index/'

r = requests.get(url=login_url,headers=headers,verify=False,proxies=free_proxy)
f = open('day5_1.html','w',encoding='ISO-8859-1')
f.write(r.text)
f.close()

day 6

  正则

    re.S  re.I

  xpath

    知道这几点就够用了

'''
/ 根节点
// 跨节点
定位精确的标签  //a[@属性='属性值']
获取标签包裹的内容  /text()
获取标签的属性值 /a[@id='xx']/@href

xpath返回的是列表

'''
'''
    //li[5]  li 是平级标签 ok
    //a[3]   如果a 不是平级标签,那下标取值的方法不好使
'''
'''
http://bbs.talkop.com/
抓取海贼王论坛

收获(都很牛逼)
    1 发现用类写爬虫 比用函数写爬虫爽一些,有些参数不用一直传,都在__init__中,在这里就是self.data_list。
    2 json 终于意识到json的价值了,把列表类型转换成json类型,保存在文件中,可以从文件中copy出来,有转化json类型的网站,直接转化下,就可以看到其中的数据了
    3 etree的使用,参数是bytes类型
'''

import requests
import json
from lxml import etree


class TalkopSpider(object):
    def __init__(self):
        self.url = 'http://bbs.talkop.com/forum-fenxi-{}.html'
        self.headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0',
            }
        self.data_list = []

    def get_response(self,url):
        '''
        发请求,获取网页内容
        :param url:
        :return:
        '''
        response = requests.get(url=url,headers=self.headers)
        return response.content

    def parse_data(self,data):
        '''
        接收bytes类型页面值,解析之,获取需要提取的数据,
        :param data:
        :return:
        '''
        # data是bytes类型
        # 转类型
        x_data = etree.HTML(data)
        titles = x_data.xpath("//a[@class='s xst']/text()")
        urls = x_data.xpath("//a[@class='s xst']/@href")
        # 用这种方法,实现title,url一一对应。
        for index,title in enumerate(titles):
            news = {}
            news[title] = urls[index]
            self.data_list.append(news)


    def save_data(self):
        '''
        将列表类型转换为json类型
        :param data:
        :return:
        '''
        j_data = json.dumps(self.data_list)
        with open('day6.json','w') as f:
            f.write(j_data)

    def run(self):
        for i in range(1,10):
            url = self.url.format(i)
            data = self.get_response(url)
            self.parse_data(data)
        self.save_data()
TalkopSpider().run()

day7

  模糊匹配

    

//div[contain(@class,'xx')]

  beautifulsoup的使用

soup.find_all(name='a',class_='xx')

soup.find_all(name='a',attrs={'class':'xx'})

上面两个等价的
import requests
from bs4 import BeautifulSoup
from lxml import etree
import json


class BtcSpider(object):
    def __init__(self):
        self.url = 'http://8btc.com/forum-61-{}.html'
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"}

        # 保存列表页的数据
        self.data_list = []

        self.data_detail = []

    # 1.发请求
    def get_response(self, url):
        response = requests.get(url, headers=self.headers)
        data = response.content
        return data

    # 2.解析数据list
    def parse_list_data(self, data):

        # 1.转类型 BeautifulSoup可以接收bytes类型!!!!!!!!!!
        soup = BeautifulSoup(data, 'lxml')
        # 2.解析内容 取出 所有的类选择器的 A
        #这里拿到一直tag,就可以把tag包含的文本值,和tag对应的href一并取到!!!!!!!!!!
        title_list = soup.select('.xst')
        for title in title_list:
            list_dict_data = {}
            list_dict_data['title'] = title.get_text()
            list_dict_data['detail_url'] = title.get('href')
            self.data_list.append(list_dict_data)

    # 3.解析数据详情页
    def parse_detail_data(self, data):
        html_data = BeautifulSoup(data, 'lxml')

        # 取出问题--list[1][0]
        question = html_data.select('#thread_subject')[0].get_text()
        print(question)
        answer_list = html_data.select('.t_f')
        for answer in answer_list:
            answer_list = []
            answer_list.append(answer.get_text())

        detail_data = {
            "question": question,
            "answer": answer_list
        }

        self.data_detail.append(detail_data)

    # 3.保存数据,多写了一个参数,作为文件名!!!!!更灵活
    def save_data(self, data, file_path):
        data_str = json.dumps(data)
        with open(file_path, 'w') as f:
            f.write(data_str)

    def start(self):
        # 列表页的请求
        for i in range(1, 2):
            url = self.url.format(1)
            data = self.get_response(url)
            self.parse_list_data(data)
        self.save_data(self.data_list, "04list.json")

        # 发送详情页的请求
        for data in self.data_list:
            detail_url = data['detail_url']
            detail_data = self.get_response(detail_url)

            # 解析详情页的数据
            self.parse_detail_data(detail_data)

        self.save_data(self.data_detail, 'detail.json')


BtcSpider().start()

"""
html_data = etree.HTML(data)

        result_list = html_data.xpath('//div[contains(@id,"stickthread")]')
        result_list = html_data.xpath('//head/following-sibling::*[1]')
        print(len(result_list))
        print(result_list)
"""

day8

  json dumps/dump/loads/load

  在涉及到文件写入,读取,dump load 特别方便,省了中间一步。

  

import json

data_list = [{'name':'左国梁','age':'23'},{'name':'张先','age':'32'}]

# 方法 1 ,涉及文件读写,多了一步 转类型,把列表转换为json类型 ,比较繁琐

# j_data = json.dumps(data_list)
#
# with open('a.josn','w') as f:
#     f.write(j_data)

# 方法 2  不需要单独把data_list,转为json

json.dump(data_list,open('b.json','w'))

  跨节点的使用

    可以这样用,获取h2标签下所有的文本值

//h2[@class='niubi']//text()

day9

  mongodb的安装使用--增删改查

  https://www.cnblogs.com/linhaifeng/articles/8273498.html

  增 insert

  删 delete

  改update $set

  查 find()

原文地址:https://www.cnblogs.com/654321cc/p/11567310.html