小言_互联网的博客

BeautifulSoup 根据输入的公司名称来爬取公司的详细信息

288人阅读  评论(0)

  • 上次因工作需要去天眼查网站爬取了一些公司的详细信息,但是那速度实在是太慢了,而且爬取到一定数量之后还会弹出验证信息导致爬取中断。最近又需要爬取一次,而且数据量还比较大,用Selenium实在是太久都爬不完,所以被迫学习了下如何用BeautifulSoup来进行爬取。跟大家分享一下我对BeautifulSoup的用法。再次声明,本笔记仅用于个人学习用途,并不可以进行大数据的爬取。

1、获取headers

1、进入企查查官网进行注册并登录。
2、然后按F12弹出开发者工具,点击Network,然后你会看到企查查这个网址,点击一下

然后可以找到我们需要复制的header,这是非常关键的步骤,切记这个header是自己注册之后登录成功所获取的header,这样方便后面保存一次之后就可以在一定时间内无限访问网址进行查询的操作。

from bs4 import BeautifulSoup
import requests
import time

# 保持会话
# 新建一个session对象
sess = requests.session()

# 添加headers(header为自己登录的企查查网址,输入账号密码登录之后所显示的header,此代码的上方介绍了获取方法)
afterLogin_headers = {'User-Agent': '此代码上方介绍了获取的方法'}

# post请求(代表着登录行为,登录一次即可保存,方便后面执行查询指令)
login = {'user':'自己注册的账号','password':'密码'}
sess.post('https://www.qcc.com',data=login,headers=afterLogin_headers)

整段代码的含义为:伪装成用户进行登录行为(返回200状态码代表着登录成功)。

2、登录成功后,可根据输入的公司名称进行查询操作,得到所需要的内容。

def get_company_message(company):
    # 获取查询到的网页内容(全部)
    search = sess.get('https://www.qcc.com/search?key={}'.format(company),headers=afterLogin_headers,timeout=10)
    search.raise_for_status()
    search.encoding = 'utf-8' #linux utf-8
    soup = BeautifulSoup(search.text,features="html.parser")
    href = soup.find_all('a',{'class': 'title'})[0].get('href')
    time.sleep(4)
    # 获取查询到的网页内容(全部)
    details = sess.get(href,headers=afterLogin_headers,timeout=10)
    details.raise_for_status()
    details.encoding = 'utf-8' #linux utf-8
    details_soup = BeautifulSoup(details.text,features="html.parser")
    message = details_soup.text
    time.sleep(2)
    return message

上面的代码代表着执行了两个步骤。

  • ①查询某公司
  • ②点击进入第一位搜索结果的新网站,并返回该网址的文本内容。

3、将获取到的文本进行文本特殊化处理,并将其汇总成一个dataframe,方便后面保存为csv

import pandas as pd

def message_to_df(message,company):
    list_companys = []
    Registration_status = []
    Date_of_Establishment = []
    registered_capital = []
    contributed_capital = []
    Approved_date = []
    Unified_social_credit_code = []
    Organization_Code = []
    companyNo = []
    Taxpayer_Identification_Number = []
    sub_Industry = []
    enterprise_type = []
    Business_Term = []
    Registration_Authority = []
    staff_size = []
    Number_of_participants = []
    sub_area = []
    company_adress = []
    Business_Scope = []

    list_companys.append(company)
    Registration_status.append(message.split('登记状态')[1].split('\n')[1].split('成立日期')[0].replace(' ',''))
    Date_of_Establishment.append(message.split('成立日期')[1].split('\n')[1].replace(' ',''))
    registered_capital.append(message.split('注册资本')[1].split('人民币')[0].replace(' ',''))
    contributed_capital.append(message.split('实缴资本')[1].split('人民币')[0].replace(' ',''))
    Approved_date.append(message.split('核准日期')[1].split('\n')[1].replace(' ',''))
    try:
        credit = message.split('统一社会信用代码')[1].split('\n')[1].replace(' ','')
        Unified_social_credit_code.append(credit)
    except:
        credit = message.split('统一社会信用代码')[3].split('\n')[1].replace(' ','')
        Unified_social_credit_code.append(credit)
    Organization_Code.append(message.split('组织机构代码')[1].split('\n')[1].replace(' ',''))
    companyNo.append(message.split('工商注册号')[1].split('\n')[1].replace(' ',''))
    Taxpayer_Identification_Number.append(message.split('纳税人识别号')[1].split('\n')[1].replace(' ',''))
    try:
        sub = message.split('所属行业')[1].split('\n')[1].replace(' ','')
        sub_Industry.append(sub)
    except:
        sub = message.split('所属行业')[1].split('为')[1].split(',')[0]
        sub_Industry.append(sub)
    enterprise_type.append(message.split('企业类型')[1].split('\n')[1].replace(' ',''))
    Business_Term.append(message.split('营业期限')[1].split('登记机关')[0].split('\n')[-1].replace(' ',''))
    Registration_Authority.append(message.split('登记机关')[1].split('\n')[1].replace(' ',''))
    staff_size.append(message.split('人员规模')[1].split('人')[0].split('\n')[-1].replace(' ',''))
    Number_of_participants.append(message.split('参保人数')[1].split('所属地区')[0].replace(' ','').split('\n')[2])
    sub_area.append(message.split('所属地区')[1].split('\n')[1].replace(' ',''))
    try:
        adress = message.split('经营范围')[0].split('企业地址')[1].split('查看地图')[0].split('\n')[2].replace(' ','')
        company_adress.append(adress)
    except:
        adress = message.split('经营范围')[1].split('企业地址')[1].split()[0]
        company_adress.append(adress)
    Business_Scope.append(message.split('经营范围')[1].split('\n')[1].replace(' ',''))
    df = pd.DataFrame({'公司':company,\
                      '登记状态':Registration_status,\
                      '成立日期':Date_of_Establishment,\
                      '注册资本':registered_capital,\
                      '实缴资本':contributed_capital,\
                      '核准日期':Approved_date,\
                      '统一社会信用代码':Unified_social_credit_code,\
                      '组织机构代码':Organization_Code,\
                      '工商注册号':companyNo,\
                      '纳税人识别号':Taxpayer_Identification_Number,\
                      '所属行业':sub_Industry,\
                      '企业类型':enterprise_type,\
                      '营业期限':Business_Term,\
                      '登记机关':Registration_Authority,\
                      '人员规模':staff_size,\
                      '参保人数':Number_of_participants,\
                      '所属地区':sub_area,\
                      '企业地址':company_adress,\
                      '经营范围':Business_Scope})
    
    return df
    

这段代码是对获取到的文本内容进行文本识别处理,只能处理大部分的内容,可能会有极个别的是空值,大家有兴趣可以自己重写。

4、输入公司名称

  • 这里只是写个案例,所以随便写了个列表,一般跑自己代码的是读取自己的csv文件关于公司名称的那一列,然后转为列表)
# 测试所用
companys = ['深圳市腾讯计算机系统有限公司','阿里巴巴(中国)有限公司']

# 实际所用
# df_companys = pd.read_csv('自己目录的绝对路径/某某.csv')
# companys = df_companys['公司名称'].tolist()

5、最后执行此代码,查询companys列表中所有公司名称的详细信息并保存为csv。

for company in companys:
    try:
        messages = get_company_message(company)
    except:
        pass
    else:
        df = message_to_df(messages,company)
        if(company==companys[0]):
            df.to_csv('自己目录的绝对路径/某某.csv',index=False,header=True)
        else:
            df.to_csv('自己目录的绝对路径/某某.csv',mode='a+',index=False,header=False)
    time.sleep(1)

至此,就可以得到这两家公司的一些详细信息。

ps:如果大家在 soup.find_all(‘a’,{‘class’: ‘title’})[0].get(‘href’)这里遇到点错误,可能是天眼查那边更新了网页代码,大家可以根据这个操作来更新代码。

①按F12进入开发者调试页面

②就点击“深圳市腾讯计算机系统有限公司”这个点击操作而言,右击,然后选择“检查”选项,然后就可以看到开发者调试页面那里也自动跳转到了相关的位置。

③我们可以看到,这是一个a标签,class为title的html代码,所以,如果报错,可根据这个操作更换。比如,class改为了company_title,那代码也可对应的改为:soup.find_all(‘a’,{‘class’: ‘company_title’})[0].get(‘href’)

最后,大家需要注意的是,爬取的时候需要适当的设置一下睡眠时间,不然会被检测到是爬虫机器人在操作,可能会弹出弹窗让你验证,这样会导致循环被中断。第二个就是某个时间段爬取量尽量不要太大,不然也是会被检测到的。

此处贴上完整代码,大家可参考着学习BeautifuSoup的妙用哦。

from bs4 import BeautifulSoup
import requests
import time
# 保持会话
# 新建一个session对象
sess = requests.session()

# 添加headers(header为自己登录的企查查网址,输入账号密码登录之后所显示的header,此代码的上方介绍了获取方法)
afterLogin_headers = {'User-Agent': '此代码上方介绍了获取的方法'}

# post请求(代表着登录行为,登录一次即可保存,方便后面执行查询指令)
login = {'user':'自己注册的账号','password':'密码'}
sess.post('https://www.qcc.com',data=login,headers=afterLogin_headers)

def get_company_message(company):
    # 获取查询到的网页内容(全部)
    search = sess.get('https://www.qcc.com/search?key={}'.format(company),headers=afterLogin_headers,timeout=10)
    search.raise_for_status()
    search.encoding = 'utf-8' #linux utf-8
    soup = BeautifulSoup(search.text,features="html.parser")
    href = soup.find_all('a',{'class': 'title'})[0].get('href')
    time.sleep(4)
    # 获取查询到的网页内容(全部)
    details = sess.get(href,headers=afterLogin_headers,timeout=10)
    details.raise_for_status()
    details.encoding = 'utf-8' #linux utf-8
    details_soup = BeautifulSoup(details.text,features="html.parser")
    message = details_soup.text
    time.sleep(2)
    return message

import pandas as pd

def message_to_df(message,company):
    list_companys = []
    Registration_status = []
    Date_of_Establishment = []
    registered_capital = []
    contributed_capital = []
    Approved_date = []
    Unified_social_credit_code = []
    Organization_Code = []
    companyNo = []
    Taxpayer_Identification_Number = []
    sub_Industry = []
    enterprise_type = []
    Business_Term = []
    Registration_Authority = []
    staff_size = []
    Number_of_participants = []
    sub_area = []
    company_adress = []
    Business_Scope = []

    list_companys.append(company)
    Registration_status.append(message.split('登记状态')[1].split('\n')[1].split('成立日期')[0].replace(' ',''))
    Date_of_Establishment.append(message.split('成立日期')[1].split('\n')[1].replace(' ',''))
    registered_capital.append(message.split('注册资本')[1].split('人民币')[0].replace(' ',''))
    contributed_capital.append(message.split('实缴资本')[1].split('人民币')[0].replace(' ',''))
    Approved_date.append(message.split('核准日期')[1].split('\n')[1].replace(' ',''))
    try:
        credit = message.split('统一社会信用代码')[1].split('\n')[1].replace(' ','')
        Unified_social_credit_code.append(credit)
    except:
        credit = message.split('统一社会信用代码')[3].split('\n')[1].replace(' ','')
        Unified_social_credit_code.append(credit)
    Organization_Code.append(message.split('组织机构代码')[1].split('\n')[1].replace(' ',''))
    companyNo.append(message.split('工商注册号')[1].split('\n')[1].replace(' ',''))
    Taxpayer_Identification_Number.append(message.split('纳税人识别号')[1].split('\n')[1].replace(' ',''))
    try:
        sub = message.split('所属行业')[1].split('\n')[1].replace(' ','')
        sub_Industry.append(sub)
    except:
        sub = message.split('所属行业')[1].split('为')[1].split(',')[0]
        sub_Industry.append(sub)
    enterprise_type.append(message.split('企业类型')[1].split('\n')[1].replace(' ',''))
    Business_Term.append(message.split('营业期限')[1].split('登记机关')[0].split('\n')[-1].replace(' ',''))
    Registration_Authority.append(message.split('登记机关')[1].split('\n')[1].replace(' ',''))
    staff_size.append(message.split('人员规模')[1].split('人')[0].split('\n')[-1].replace(' ',''))
    Number_of_participants.append(message.split('参保人数')[1].split('所属地区')[0].replace(' ','').split('\n')[2])
    sub_area.append(message.split('所属地区')[1].split('\n')[1].replace(' ',''))
    try:
        adress = message.split('经营范围')[0].split('企业地址')[1].split('查看地图')[0].split('\n')[2].replace(' ','')
        company_adress.append(adress)
    except:
        adress = message.split('经营范围')[1].split('企业地址')[1].split()[0]
        company_adress.append(adress)
    Business_Scope.append(message.split('经营范围')[1].split('\n')[1].replace(' ',''))
    df = pd.DataFrame({'公司':company,\
                      '登记状态':Registration_status,\
                      '成立日期':Date_of_Establishment,\
                      '注册资本':registered_capital,\
                      '实缴资本':contributed_capital,\
                      '核准日期':Approved_date,\
                      '统一社会信用代码':Unified_social_credit_code,\
                      '组织机构代码':Organization_Code,\
                      '工商注册号':companyNo,\
                      '纳税人识别号':Taxpayer_Identification_Number,\
                      '所属行业':sub_Industry,\
                      '企业类型':enterprise_type,\
                      '营业期限':Business_Term,\
                      '登记机关':Registration_Authority,\
                      '人员规模':staff_size,\
                      '参保人数':Number_of_participants,\
                      '所属地区':sub_area,\
                      '企业地址':company_adress,\
                      '经营范围':Business_Scope})
    
    return df

# 测试所用
companys = ['深圳市腾讯计算机系统有限公司','阿里巴巴(中国)有限公司']

# 实际所用
# df_companys = pd.read_csv('自己目录的绝对路径/某某.csv')
# companys = df_companys['公司名称'].tolist()

for company in companys:
    try:
        messages = get_company_message(company)
    except:
        pass
    else:
        df = message_to_df(messages,company)
        if(company==companys[0]):
            df.to_csv('自己目录的绝对路径/某某.csv',index=False,header=True)
        else:
            df.to_csv('自己目录的绝对路径/某某.csv',mode='a+',index=False,header=False)
    time.sleep(1)

注明:转载需注明本原地址链接,利用代码进行非法行为与本人无关。

(一经发现有人直接复制粘贴,请大家帮忙举报一下,上次那篇Selenium的博客被人直接复制粘贴拿去发表了,居然阅读量比我的还高,要不是有粉丝跟我说我还不知道,真的是)

创作不易啊。如果大家觉得这个笔记对你们有用的,麻烦帮忙点个赞加关注哦。


转载:https://blog.csdn.net/qq_40694671/article/details/110671900
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场