python爬虫接单需要具备哪些技能——记一次爬虫接单实践

距离上次接单爬取数据已经有将近2年时间了,一方面是没有去刻意找单子,另一个方面这个行业变得越来越专业化,同时价格也越来越低让人咂舌,但最重要的原因是工作和学习的东西太多,有点忙不过来。但是最近这个单子是老客户,给出的价格也还可以接受,所以经过考虑还是把单子接下来了,其实工作未开始就已经能够预见其中的难点是应对验证码的反爬,因为数据量不是很大我还是采用了最拙略的办法,亲自拿起鼠标操作验证码验证,但结果搞得我有点有些不爽,所以在接下来会再写一篇用python破解百度旋转验证码的技术博客,用以表示爬虫工程师的愤怒!言归正传,直接开干!

通过本次实践你将会学到以下技术:

python文件读写(r表示读,w表示写,b表示以二进制编码读写,a表示追加写入)with open(file,'rb') as f:
    page = f.read()
文件目录遍历方法os.listdir()for each in os.listdir(path):
        file = os.path.join(path,each)
        print(file)
windows和Linux下chromedriver的配置
selenium驱动本地已打开的chrome页面进行单步调试见2.数据采集代码
xpath提取页面数据见3.数据解析代码
pandas清洗数据见4.数据清洗
文件移动模块shutil的使用见3.数据解析代码

1、整体爬取思路分解:

1>.通过selenium打开目标网站,通过提供的企业名称列表一个一个放到搜索框中进行搜索,并把结果页面通过.html保存到本地。
2>.对采集到的html数据进行解析,并存入Excel。
3>.对上一步中提取的数据进行格式转换、去重、垃圾字符清除,得到部分最终数据。
4>.对采集失败的数据进行过滤提取,并重新采集也就是重复以上三个步骤。
5>.数据合并,将多次采集和清洗的数据合并到一起,得到最终数据,一手交数据一手收款。
6>.休养恢复

2.数据采集代码

# coding=utf-8

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from lxml import etree
import time

#这部分是selenium单步调试启动本地chrome页面并指定端口与临时数据存放目录的,配合下面的注释使用
'''/opt/google/chrome/google-chrome --no-sandbox --remote-debugging-port=9222 --user-data-dir="/tmp/userdata" &'''

# 读取包含企业名称的excel并将其转换为列表
def read_excel():
    df = pd.read_excel("company_name.xlsx")
    name_list = df["企业名称"].to_numpy().tolist()
    return name_list

# 采集入口
def main():
    companys = read_excel()
    # chrome_options = Options()
    chrome_driver = r'/home/ttk/桌面/chrome/chromedriver'
    # chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
    # b = webdriver.Chrome(chrome_driver, options=chrome_options)
    b = webdriver.Chrome(chrome_driver)
    b.get('https://aiqicha.baidu.com/company_detail_46022060497321')
    try:
        # 用于记录采集到的位置,失败后方便下次自动从上次的位置开始
        with open("number.txt") as f:
            i = int(f.read())
    except Exception as e:
        i=0
    while True:
        print(i)
        company = companys[i]
        element = b.find_element_by_id("aqc-header-search-input")
        element.clear()
        element.send_keys(company)
        time.sleep(1)
        # print(b.window_handles)
        b.find_element_by_class_name("search-btn").click()
        time.sleep(3)
        ################################## 以下代码区间段是避开页面元素不能点击的情况,可以尝 
        #试用click()点击替换
        html_ = etree.HTML(b.page_source)
        try:
            new_url = html_.xpath('(//h3[@class="title"]/a/@href)[1]')[0]
        except Exception as e:
            b.quit()
            i+=1
            with open("number.txt", 'w') as f:
                f.write(str(i))
        print(new_url)
        with open("url.txt",'a') as n:
            n.write(new_url+"\n")
        b.get('https://aiqicha.baidu.com%s'%new_url)
        ####################################
        time.sleep(3)
        html = b.page_source
        with open("./failed/%s_%d.html"%(company,i),"wb") as f:
            f.write(html.encode("utf-8"))
        i+=1
        with open("number.txt",'w') as f:
            f.write(str(i))

if __name__=="__main__":
    while True:
        try:
            main()
        except Exception as e:
            print(e)
            time.sleep(5)

3.数据解析代码

# coding=utf-8

import os
import pandas as pd
from lxml import etree
import shutil



def parse():
    base = os.getcwd()
    path = os.path.join(base,"data") #待解析数据在data目录下
    dist =  os.path.join(base,"error") #解析失败数据移动到error进行后续重采
    print(path)
    dic_list = []
    for each in os.listdir(path):
        file = os.path.join(path,each)
        print(each)
        with open(file,'rb') as f:
            page = f.read()
        hml = etree.HTML(page)
        try:
            trs = hml.xpath('//div[@id="basic-business"]/table//tr')
        except Exception as e:
            print(e)
            shutil.move(file,dist)
            continue
        title = each.strip(".html").split("_")
        dic={"序号":int(title[1]),"企业名称":title[0]}
        for tr in trs:
            tr_index = tr.xpath(".//td")
            text = []
            i=1
            for eve in tr_index:
                if i%2==1:
                    key = eve.xpath("string(.)") # 提取当前节点下所有子节点中的文本数据
                elif i%2==0:
                    if key.strip() =="法定代表人":
                        value = eve.xpath('./div[2]/a[1]/text()|./div[2]/p/text()')[0]
                    elif key.strip() in ("执行事物合伙人","执行事务合伙人","负责人","投资人"):
                        key="法定代表人"
                        value = eve.xpath('./div[2]/p/text()|./div[2]/a[1]/text()')[0]
                    else:
                        value = eve.xpath("string(.)")
                    dic.update({key.strip():value.lstrip()})
                i+=1

        dic_list.append(dic)
    df = pd.DataFrame(dic_list)
    df.sort_values(by="序号",inplace=True,ascending=True)
    df.to_excel("total.xlsx",index=False)
if __name__ == '__main__':
    parse()

4.数据清洗

# coding=utf-8

import pandas as pd


def clean_data():
    df = pd.read_excel("total.xlsx")
    need= df.loc[:,["法定代表人","企业名称","经营状态","注册资本","所属行业","统一社会信用代码","工商注册号","组织机构代码","成立日期","行政区划","经营范围","核准日期"]]
    print(need.shape)
    need.dropna(how="all",inplace=True) # 删除空行
    # print(need)
    need.loc[:, "姓名"] = need["法定代表人"].str.strip().str.strip('"')
    need.loc[:,"经营状态"] = need["经营状态"].str.strip()
    need.loc[:,"注册资本(万元)"] = need["注册资本"].str.strip().str.replace("万","")
    need.loc[:,"成立年份"] = need["成立日期"].str.split("-",expand=True)[0]

    need.loc[need["经营状态"].isin(["吊销","注销"])==True,"终止年份"] = need["核准日期"]
    print(need.shape)
    need.dropna(subset=["经营状态","注册资本","所属行业","统一社会信用代码","工商注册号","组织机构代码","成立日期","行政区划","经营范围"],inplace=True) # 删除空行
    print(need.shape)
    result = need.loc[:,['姓名','企业名称','注册资本(万元)',"经营状态",'所属行业','成立年份','终止年份','行政区划','统一社会信用代码','工商注册号','组织机构代码',"经营范围"]]
    result.to_excel("result_total.xlsx",index=False)


if __name__=="__main__":
    clean_data()

5.验证码截图(下次写这个的python解决方案

原文出自:python爬虫接单需要具备哪些技能——记一次爬虫接单实践 – 醉乌苏

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值