Scrapyフレームワークを使用して企業名录 웹사이트から企業情報を取得し、MySQLデータベースに保存する方法を説明します。 примерно 22万件のデータを処理する必要があります。
以上の実装により、大量の企業データを効率的にスクレイピングし、MySQLデータベースに保存することが可能になります。実行際は設定ファイルを適切に調整し、robots.txtの遵守やリクエスト間隔の調整など、マナー的なスクレイピングをお願いします。
第一步:Itemクラス定義
まず、スクレイピング対象のフィールドをItemクラスで定義します。import scrapy
class CompanyItem(scrapy.Item):
prefecture_name = scrapy.Field()
district_name = scrapy.Field()
company_name = scrapy.Field()
company_address = scrapy.Field()
telephone = scrapy.Field()
mobile = scrapy.Field()
第二步:Spiderロジック実装
Spiderクラスを定義し、ウェブページの解析処理を実装します。import scrapy
from scrapy.http import Request
from lxml import etree
class CompanySpider(scrapy.Spider):
name = 'company_spider'
def start_requests(self):
base_url = 'http://example.business.jp/'
yield Request(url=base_url, callback=self.parse_main)
def parse_main(self, response):
html_tree = etree.HTML(response.text)
rows = html_tree.xpath('//table/tbody/tr')
for row in rows:
cells = row.xpath('./td[2]//a')
for cell in cells:
link = cell.get('href')
if link:
full_url = 'http://example.business.jp/' + str(link)
yield Request(url=full_url, callback=self.parse_detail)
def parse_detail(self, response):
html_tree = etree.HTML(response.text)
data_rows = html_tree.xpath('//table/tbody/tr')
for record in data_rows[2:]:
text_content = record.xpath('string()')
field_list = text_content.replace(' ', '').replace('\r', '').split('\n')
field_list = [f.strip() for f in field_list if f.strip()]
attributes = record.xpath('./td[4]/@*')
attr_value = attributes[-1].replace("'", '') if attributes else ''
if '名称' in data_rows[1].xpath('string()').replace(' ', '').replace('\r', '').split('\n')[3]:
prefecture = field_list[0] if len(field_list) > 0 else ''
district = field_list[2] if len(field_list) > 2 else ''
if record.xpath('./td[3]/@*')[-1].replace("'", '') == 'nowrap':
company = field_list[3] if len(field_list) > 3 else ''
else:
company = attr_value
address = field_list[4] if len(field_list) > 4 else ''
phone = field_list[5] if len(field_list) > 5 else ''
mobile_phone = field_list[6] if len(field_list) > 6 else ''
else:
prefecture = field_list[2] if len(field_list) > 2 else ''
district = field_list[3] if len(field_list) > 3 else ''
company = attr_value
address = field_list[5] if len(field_list) > 5 else ''
phone = field_list[6] if len(field_list) > 6 else ''
mobile_phone = field_list[7] if len(field_list) > 7 else ''
item = CompanyItem()
item['prefecture_name'] = prefecture
item['district_name'] = district
item['company_name'] = company
item['company_address'] = address
item['telephone'] = phone
item['mobile'] = mobile_phone
yield item
第三步:Pipeline設定
settings.pyでPipelineを有効化します。ITEM_PIPELINES = {
'company_spider.pipelines.CompanySpiderPipeline': 300,
}
第四步:データベース保存処理
PipelineクラスでMySQLへの保存処理を実装します。import pymysql
class CompanySpiderPipeline:
def __init__(self):
self.connection = pymysql.connect(
host='localhost',
user='root',
password='your_password',
port=3306,
database='company_db',
charset='utf8mb4'
)
self.cursor = self.connection.cursor()
self.cursor.execute("""
CREATE TABLE IF NOT EXISTS company_directory (
prefecture_name VARCHAR(100),
district_name VARCHAR(100),
company_name VARCHAR(200),
company_address VARCHAR(200),
telephone VARCHAR(50),
mobile VARCHAR(50)
)
""")
self.connection.commit()
def process_item(self, item, spider):
sql = '''INSERT INTO company_directory
(prefecture_name, district_name, company_name,
company_address, telephone, mobile)
VALUES (%s, %s, %s, %s, %s, %s)'''
try:
self.connection.ping(reconnect=True)
self.cursor.execute(sql, (
item['prefecture_name'],
item['district_name'],
item['company_name'],
item['company_address'],
item['telephone'],
item['mobile']
))
self.connection.commit()
except Exception as e:
self.connection.rollback()
spider.logger.error(f'Database error: {e}')
return item
def close_spider(self, spider):
self.cursor.close()
self.connection.close()